USB Device Programming class project. This project allows a Python/Tk program running on a PC host to monitor/control a test-CPU programmed into an altera development board.
Dependencies: C12832_lcd USBDevice mbed-rtos mbed mmSPI
Diff: mmRTL/cpu.txt
- Revision:
- 3:659ffc90b59e
- Child:
- 7:d1aca9ccbab8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmRTL/cpu.txt Sun Sep 01 02:53:39 2013 +0000 @@ -0,0 +1,514 @@ +/*----------------------------------copyright---//----------------------------*/ +// licensed for personal and academic use. +// commercial use must be approved by the account-holder of +// gated.clock@gmail.com +/*-----------------------------------module-----//----------------------------*/ + module cpu + ( + iMOSI, + oMISO, + iSPIclk, + iCPUclk, + iKEY, + iSW, + oLEDR, + oLEDG, + oDummyLoad + ); +/*--------------------------------description---//------------------------------ + the demonstration cpu datapath. + + the CPU consists of + R0 - 8-bit register and accumulator. + R1 - 8-bit register and main-memory address register. + R2 - 8-bit register and main-memory high data byte. + R3 - 8-bit register and main-memory low data byte. + PC - 8-bit program counter. + IR - 16-bit instruction register. + ID - combinatorial instruction decoder. + MM - 16-bit-wide x 256-address Main Memory. + + the instruction words is sixteen bits long, and is comprised of + <15:13> = source resource. + <12:10> = destination resource. + < 9> = write-enable. + < 8> = program-counter-enable. + < 7: 0> = immediate data. + + the registers (U00 through U05) have a iSel input which define the source. + the instruction decoder (U06) enables the loading of the destinations. + + the SPI shadow registers (U19-U25) monitor the CPU state, and can + control the CPU state by asserting U19's bits 1 and 2. + + U08 provides a shadow register load-enable pulse which + begins at the falling edge of a CPU clock and ends at + the falling edge of the next SPI clock, allowing the shadow + registers the ability to capture the state of the CPU. + + U30 routes internal nets out to the green LED bank according + to the setting of switches SW<3:0>. + +-------------------------------------notes------//------------------------------ + + fpga board pin assignments. + + + project: + MOSI P17 + MISO D15 + SPIclk E20 + CPUclk E14 + + + key3 T21 + key2 T22 + key1 R21 + key0 R22 iRstn + + sw9 L2 + sw8 M1 + sw7 M2 + sw6 U11 + sw5 U12 + sw4 W12 + sw3 V12 + sw2 M22 + sw1 L21 + sw0 L22 + + ledr9 R17 + ledr8 R18 + ledr7 U18 + ledr6 Y18 + ledr5 V19 + ledr4 T18 + ledr3 Y19 + ledr2 U19 + ledr1 R19 + ledr0 R20 + + ledg7 Y21 + ledg6 Y22 + ledg5 W21 + ledg4 W22 + ledg3 V21 + ledg2 V22 + ledg1 U21 + ledg0 U22 +------------------------------------defines-----//----------------------------*/ +/*-----------------------------------ports------//----------------------------*/ + input iMOSI; // SPI input. + output oMISO; // SPI output. + input iSPIclk; // SPI clock. + input iCPUclk; // CPU clock. + input [ 3:0] iKEY; // keypress. + input [ 9:0] iSW; // slide-switches. + output [ 9:0] oLEDR; // red LED bank. + output [ 7:0] oLEDG; // green LED bank. + output oDummyLoad; // anti-optimization. +/*-----------------------------------wires------//----------------------------*/ + wire iMOSI; // SPI input. + wire oMISO; // SPI output. + wire iSPIclk; // SPI clock. + wire iCPUclk; // CPU clock. + wire [ 3:0] iKEY; // keypress. + wire [ 9:0] iSW; // slide-switches. + wire [ 9:0] oLEDR; // red LED bank. + wire [ 7:0] oLEDG; // green LED bank. + + wire wCEPC; // program counter count-enable. + wire [15:0] wIR; // instruction register. + wire wLEIR; // instruction register load-enable. + wire wLEPC; // program counter load-enable. + wire wLER0; // R0 load-enable. + wire wLER1; // R1 load-enable. + wire wLER2; // R2 load-enable. + wire wLER3; // R3 load-enable. + wire [15:0] wMMD; // main-memory data-out. + wire [15:0] wMMI; // main-memory instruction-out. + wire [ 7:0] wPC; // program-counter. + wire [ 7:0] wR0; // R0. + wire [ 7:0] wR1; // R1. + wire [ 7:0] wR2; // R2. + wire [ 7:0] wR3; // R3. + wire wRstn; // system reset. + wire [ 2:0] wSel; // common data-in selector. + wire [ 7:0] wShadow0; // R0 shadow register. + wire [ 7:0] wShadow1; // R1 shadow register. + wire [ 7:0] wShadow2; // R2 shadow register. + wire [ 7:0] wShadow3; // R3 shadow register. + wire [15:0] wShadowIR; // instruction register shadow. + wire [ 7:0] wShadowPC; // program counter shadow. + wire wSIR; // instruction register shadow shift-up. + wire wSPC; // program counter shadow shift-up. + wire wSR0; // R0 shadow shift-up. + wire wSR1; // R1 shadow shift-up. + wire wSR2; // R2 shadow shift-up. + wire wSR3; // R3 shadow shift-up. + wire wWE; // write-enable pulse. + wire [ 7:0] wImmediate; // immediate data. + wire [ 7:0] wSpiControl; // from spi control register. + wire wSquelch; // from spi control register. + wire wBypassIR; // from spi control register. + wire wLoadShadows; // shadow registers parallel load. + + // not currently used. + wire [ 7:0] wGreenLEDBus7; // green LED bus. + wire [ 7:0] wGreenLEDBus6; // green LED bus. + wire [ 7:0] wGreenLEDBus5; // green LED bus. + wire [ 7:0] wGreenLEDBus4; // green LED bus. + wire [ 7:0] wGreenLEDBus3; // green LED bus. + wire [ 7:0] wGreenLEDBus2; // green LED bus. + wire [ 7:0] wGreenLEDBus1; // green LED bus. + wire [ 7:0] wGreenLEDBus0; // green LED bus. + wire oDummyLoad; // anti-optimization. + wire [ 3:0] wTrigger; // trigger control. +/*---------------------------------registers----//----------------------------*/ +/*---------------------------------variables----//----------------------------*/ +/*---------------------------------parameters---//----------------------------*/ +/*-----------------------------------clocks-----//----------------------------*/ +/*---------------------------------instances----//----------------------------*/ + +//--- begin regular CPU section. + + + reg_08 U00_R0 // CPU R0. + ( + .oParallel (wR0), + .iParallel7 (wShadow0), + .iParallel6 (wR1 + wR2), // adder. + .iParallel5 (wImmediate), + .iParallel4 (wR0), + .iParallel3 (wR3), + .iParallel2 (wR2), + .iParallel1 (wR1), + .iParallel0 (wR0), // needed for zero vector no-op. + .iSel (wSel), + .oSerial (), + .iSerial (1'b0), + .iLoadEnable (wLER0), + .iShiftEnable(1'b0), + .iResetN (wRstn), + .iClk (iCPUclk) + ); + + + + reg_08 U01_R1 // CPU R1. + ( + .oParallel (wR1), + .iParallel7 (wShadow1), + .iParallel6 (wMMD[7:0]), + .iParallel5 (wImmediate), + .iParallel4 (wR1), + .iParallel3 (wR3), + .iParallel2 (wR2), + .iParallel1 (wR1), + .iParallel0 (wR0), + .iSel (wSel), + .oSerial (), + .iSerial (1'b0), + .iLoadEnable (wLER1), + .iShiftEnable(1'b0), + .iResetN (wRstn), + .iClk (iCPUclk) + ); + + + + reg_08 U02_R2 // CPU R2. + ( + .oParallel (wR2), + .iParallel7 (wShadow2), + .iParallel6 (wMMD[15:8]), + .iParallel5 (wImmediate), + .iParallel4 (wR2), + .iParallel3 (wR3), + .iParallel2 (wR2), + .iParallel1 (wR1), + .iParallel0 (wR0), + .iSel (wSel), + .oSerial (), + .iSerial (1'b0), + .iLoadEnable (wLER2), + .iShiftEnable(1'b0), + .iResetN (wRstn), + .iClk (iCPUclk) + ); + + + reg_08 U03_R3 // CPU R3. + ( + .oParallel (wR3), + .iParallel7 (wShadow3), + .iParallel6 (wMMD[7:0]), + .iParallel5 (wImmediate), + .iParallel4 (wR3), + .iParallel3 (wR3), + .iParallel2 (wR2), + .iParallel1 (wR1), + .iParallel0 (wR0), + .iSel (wSel), + .oSerial (), + .iSerial (1'b0), + .iLoadEnable (wLER3), + .iShiftEnable(1'b0), + .iResetN (wRstn), + .iClk (iCPUclk) + ); + + + + counter_08 U04_PC // CPU program counter. + ( + .oCount (wPC), + .iParallel7 (wShadowPC), + .iParallel6 (wMMD[7:0]), + .iParallel5 (wImmediate), + .iParallel4 (wPC), + .iParallel3 (wR3), + .iParallel2 (wR2), + .iParallel1 (wR1), + .iParallel0 (wR0), + .iSel (wSel), + .oSerial (), + .iSerial (1'b0), + .iLoadEnable (wLEPC), + .iShiftEnable(1'b0), + .iCountEnable(wCEPC), + .iResetN (wRstn), + .iClk (iCPUclk) + ); + + + reg_16 U05_IR // CPU instruction register. + ( + .oParallel (wIR), // IR state. + .iParallel1 (wShadowIR), // IR shadow state. + .iParallel0 (wMMI), // MM output. + .iSel (wSpiControl[2]), // special control. + .oSerial (), + .iSerial (1'b0), + .iLoadEnable (wLEIR), + .iShiftEnable(1'b0), + .iResetN (wRstn), + .iClk (iCPUclk) + ); + + + instruction_decoder U06_ID // instruction decoder. + ( + .iSquelch (wSquelch), // squelch when writing to IR. + .iIR (wIR), // instruction register. + .iBypass (wShadowIR), // IR bypass from SPI. + .iBypassIR (wBypassIR), // bypass the IR. + .oSel (wSel), // common data-in selector. + .oLER0 (wLER0), // R0 load-enable. + .oLER1 (wLER1), // R1 load-enable. + .oLER2 (wLER2), // R2 load-enable. + .oLER3 (wLER3), // R3 load-enable. + .oLEPC (wLEPC), // PC load-enable. + .oWE (wWE), // write-enable pulse. + .oCEPC (wCEPC), // PC count-enable. + .oImmediate(wImmediate) // immediate data. + ); + + + + // main memory: + // the program counter reads from read-port-0. + // the R2:R1 port reads from read-port-1. + // the R2:R1 port writes to the write port. + // the R2:R1 port reads/writes using address from R3. + + + main_memory U07_MM // main-memory. + ( + .iReadAddress1(wR3), // from R3. + .iReadAddress0(wPC), // from PC + .iWriteAddress(wR3), // from R3 + .oReadData1 (wMMD), // to <R2:R1> + .oReadData0 (wMMI), // to IR. + .iWriteData ({wR2,wR1}), // from <R2:R1>. + .iWE (wWE), // from the instruction decoder. + .iCPUclk (iCPUclk) + ); + + + // load shadow-registers upon rising + // edge of first SPI clock following + // the falling edge of a CPU clock. + shadow_load_control U08_shadow_load // shadow-register load control. + ( + .iCPUclk(iCPUclk), + .iSPIclk(iSPIclk), + .iRstn(wRstn), + .oLoadEnable(wLoadShadows) + ); + + +//--- begin SPI shadow-scan section. + + + // the SPI scan registers are generally + // given the term 'shadow registers'. + + + scan_08 U19_spi_control // top of SPI scan chain, used for control. + ( + .oParallel (wSpiControl), // green LED select 7. + .iParallel (wSpiControl), // self-refresh. + .oSerial (oMISO), + .iSerial (wSR0), + .iLoadEnable (wLoadShadows), + .iShiftEnable(1'b1), + .iResetN (wRstn), + .iClk (iSPIclk) + ); + + + + scan_08 U20_shadowR0 // R0 shadow register. + ( + .oParallel (wShadow0), // green LED select 6. + .iParallel (wR0), + .oSerial (wSR0), + .iSerial (wSR1), + .iLoadEnable (wLoadShadows), + .iShiftEnable(1'b1), + .iResetN (wRstn), + .iClk (iSPIclk) + ); + + scan_08 U21_shadowR1 // R1 shadow register. + ( + .oParallel (wShadow1), // green LED select 5. + .iParallel (wR1), + .oSerial (wSR1), + .iSerial (wSR2), + .iLoadEnable (wLoadShadows), + .iShiftEnable(1'b1), + .iResetN (wRstn), + .iClk (iSPIclk) + ); + + scan_08 U22_shadowR2 // R2 shadow register. + ( + .oParallel (wShadow2), // green LED select 4. + .iParallel (wR2), + .oSerial (wSR2), + .iSerial (wSR3), + .iLoadEnable (wLoadShadows), + .iShiftEnable(1'b1), + .iResetN (wRstn), + .iClk (iSPIclk) + ); + + scan_08 U23_shadowR3 // R3 shadow register. + ( + .oParallel (wShadow3), // green LED select 3. + .iParallel (wR3), + .oSerial (wSR3), + .iSerial (wSPC), + .iLoadEnable (wLoadShadows), + .iShiftEnable(1'b1), + .iResetN (wRstn), + .iClk (iSPIclk) + ); + + scan_08 U24_shadowPC // program-counter shadow register. + ( + .oParallel (wShadowPC), // green LED select 2. + .iParallel (wPC), + .oSerial (wSPC), + .iSerial (wSIR), + .iLoadEnable (wLoadShadows), + .iShiftEnable(1'b1), + .iResetN (wRstn), + .iClk (iSPIclk) + ); + + scan_16 U25_shadowIR // instruction-register shadow register. + ( + .oParallel (wShadowIR), // green LED select 1,0. + .iParallel (wIR), + .oSerial (wSIR), + .iSerial (iMOSI), + .iLoadEnable (wLoadShadows), + .iShiftEnable(1'b1), + .iResetN (wRstn), + .iClk (iSPIclk) + ); + + + +//--- begin green LED signal-monitoring section. + + + + mux8x16 U30_green_led_mux // green LED diagnostic mux. + ( + .iDin15({wLER0,wLER1,wLER2,wLER3,wLEPC,wLEIR,wWE,wCEPC}), + .iDin14(wIR[15:8]), // IR-H. + .iDin13(wIR[7:0]), // IR-L. + .iDin12(wPC), // PC. + .iDin11(wR3), // R3. + .iDin10(wR2), // R2. + .iDin9 (wR1), // R1. + .iDin8 (wR0), // R0. + .iDin7 (wSpiControl), // SPI control. + .iDin6 (wShadowIR[15:8]), // IR-H shadow. + .iDin5 (wShadowIR[7:0]), // IR-L shadow. + .iDin4 (wShadowPC), // PC shadow. + .iDin3 (wShadow3), // R3 shadow. + .iDin2 (wShadow2), // R2 shadow. + .iDin1 (wShadow1), // R1 shadow. + .iDin0 (wShadow0), // R0 shadow. + .iSel (iSW[3:0]), // mux-select. + .oDout (oLEDG) // to green LED bank. + ); +/*-----------------------------------logic------//----------------------------*/ + assign wRstn = iKEY[0]; // pushbutton system reset. + assign wSquelch = wSpiControl[2]; // for python squelching ins. decode. + assign wBypassIR = wSpiControl[1]; // for python controlling CPU. + assign wTrigger = wSpiControl[7:4]; // for signaltap triggering, not used. + + // load instruction register + // if neither or both shadow + // control signals asserted. + assign wLEIR = !(wSquelch ^ wBypassIR); + + + assign oLEDR[9] = 1'b0; // red LED hookup. + assign oLEDR[8] = 1'b0; + assign oLEDR[7] = wSel[2]; + assign oLEDR[6] = wSel[1]; + assign oLEDR[5] = wSel[0]; + assign oLEDR[4] = wRstn; + assign oLEDR[3] = iCPUclk; + assign oLEDR[2] = oMISO; + assign oLEDR[1] = iMOSI; + assign oLEDR[0] = iSPIclk; + + + // signals not to be optimized + // out, place here. + assign oDummyLoad = (|wShadowIR) | wSIR | (|wSpiControl) | (|wTrigger); +/*-------------------------------*/endmodule/*--------------------------------*/ + + + + + + + + + + + + + + + +