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
mmRTL/cpu.txt
- Committer:
- gatedClock
- Date:
- 2013-09-01
- Revision:
- 12:d10f526ca443
- Parent:
- 7:d1aca9ccbab8
File content as of revision 12:d10f526ca443:
/*----------------------------------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, // SPI data-in from mbed module. oMISO, // SPI data-out to mbed module. iSPIclk, // SPI clock in from mbed module. iCPUclk, // CPU clock in from mbed module. iKEY, // altera board pushbuttons. iSW, // altera board slider switches. oLEDR, // altera board red LED bank. oLEDG, // altera board green LED bank. oDummyLoad // anti-optimization dummy pin. ); /*--------------------------------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 data-in from mbed module. output oMISO; // SPI data-out to mbed module. input iSPIclk; // SPI clock in from mbed module. input iCPUclk; // CPU clock in from mbed module. input [ 3:0] iKEY; // altera board pushbuttons. input [ 9:0] iSW; // altera board slider switches. output [ 9:0] oLEDR; // altera board red LED bank. output [ 7:0] oLEDG; // altera board green LED bank. output oDummyLoad; // anti-optimization dummy pin. /*-----------------------------------wires------//----------------------------*/ wire iMOSI; // SPI data-in from mbed module. wire oMISO; // SPI data-out to mbed module. wire iSPIclk; // SPI clock in from mbed module. wire iCPUclk; // CPU clock in from mbed module. wire [ 3:0] iKEY; // altera board pushbuttons. wire [ 9:0] iSW; // altera board slider switches. wire [ 9:0] oLEDR; // altera board red LED bank. wire [ 7:0] oLEDG; // altera board green LED bank. wire oDummyLoad; // anti-optimization dummy pin. 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 [ 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/*--------------------------------*/