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:
7:d1aca9ccbab8
Parent:
3:659ffc90b59e
Child:
12:d10f526ca443

File content as of revision 7:d1aca9ccbab8:

/*----------------------------------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/*--------------------------------*/