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/instruction_decoder.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 instruction_decoder
        (
          iSquelch,                             // disrupt output enables.
          iIR,                                  // instruction register.
          iBypass,                              // instruction from SPI.
          iBypassIR,                            // override the IR.
          oSel,                                 // common data-in selector.
          oLER0,                                // R0 load-enable.
          oLER1,                                // R1 load-enable.
          oLER2,                                // R2 load-enable.
          oLER3,                                // R3 load-enable.
          oLEPC,                                // PC load-enable.
          oWE,                                  // write-enable pulse.
          oCEPC,                                // PC count-enable.
          oImmediate                            // immediate data.
        );
/*--------------------------------description-----------------------------------
        the instruction decoder.  
-------------------------------------notes--------------------------------------
        this instruction decoder operates in three different 'modes'.
        1. nominal mode: the instruction word is decoded as per the CPU spec.
        2. regular test mode: the instruction register is ignored, and instead
           this decoder makes use of iBypass, which is the instruction pattern
           provided by the instruction word shadow register (which is part of
           the spi scan chain).  this allows the python code to take over the
           operation of the CPU.
        3. IR-write test mode: a special-case mode which occurs when python
           writes to the instruction register.  in this case, the outputs of
           this decoder which are used to provide load-enables to CPU 
           resources, must be squelched.  this is because we don't want the
           python-written instruction register content to be decoded and
           the decoded signals sent into the CPU.  why?  because most likely
           the python-write to the IR is only to check that it can be done,
           and if the result of such a write were allowed to propagate, then
           the other registers may be arbitrarily updated, confusing the
           user at the python end.
------------------------------------defines-----------------------------------*/
/*-----------------------------------ports------------------------------------*/
        input           iSquelch;               // disrupt output enables.
        input   [15:0]  iIR;                    // instruction register.
        input   [15:0]  iBypass;                // instruction from SPI.
        input           iBypassIR;              // override the IR.
        output  [ 2:0]  oSel;                   // common data-in selector.
        output          oLER0;                  // R0 load-enable.
        output          oLER1;                  // R1 load-enable.
        output          oLER2;                  // R2 load-enable.
        output          oLER3;                  // R3 load-enable.
        output          oLEPC;                  // PC load-enable.
        output          oWE;                    // write-enable pulse.
        output          oCEPC;                  // PC count-enable.
        output  [ 7:0]  oImmediate;             // immediate data.
/*-----------------------------------wires------------------------------------*/
        wire            iSquelch;               // disrupt output enables.
        wire    [15:0]  iIR;                    // instruction register.
        wire    [15:0]  iBypass;                // instruction from SPI.
        wire            iBypassIR;              // override the IR.
        wire    [ 2:0]  oSel;                   // common data-in selector.
        wire            oLER0;                  // R0 load-enable.
        wire            oLER1;                  // R1 load-enable.
        wire            oLER2;                  // R2 load-enable.
        wire            oLER3;                  // R3 load-enable.
        wire            oLEPC;                  // PC load-enable.
        wire            oWE;                    // write-enable pulse.
        wire            oCEPC;                  // PC count-enable.
        wire    [ 7:0]  oImmediate;             // immediate data.
/*---------------------------------registers----------------------------------*/
        reg     [15:0]  rIR;                    // instruction.
        reg             rLER0;                  // R0 load-enable.
        reg             rLER1;                  // R1 load-enable.
        reg             rLER2;                  // R2 load-enable.
        reg             rLER3;                  // R3 load-enable.
        reg             rLEPC;                  // PC load-enable.
/*---------------------------------variables----------------------------------*/
/*---------------------------------parameters---------------------------------*/
/*-----------------------------------clocks-----------------------------------*/
/*---------------------------------instances----------------------------------*/
/*-----------------------------------logic------------------------------------*/


        always @ (rIR)
        case     (rIR[12:10])                   // decode the load-enables.

          7 : begin                             // no register.
                rLER0  = 1'b0;
                rLER1  = 1'b0;
                rLER2  = 1'b0;
                rLER3  = 1'b0;
                rLEPC  = 1'b0;
              end

          6 : begin                             // no register.
                rLER0  = 1'b0;
                rLER1  = 1'b0;
                rLER2  = 1'b0;
                rLER3  = 1'b0;
                rLEPC  = 1'b0;  
              end

          5 : begin                             // no register.
                rLER0  = 1'b0;
                rLER1  = 1'b0;
                rLER2  = 1'b0;
                rLER3  = 1'b0;
                rLEPC  = 1'b0;          
              end

          4 : begin                             // PC
                rLER0  = 1'b0;
                rLER1  = 1'b0;
                rLER2  = 1'b0;
                rLER3  = 1'b0;
                rLEPC  = 1'b1;                  
              end

          3 : begin                             // R3
                rLER0  = 1'b0;
                rLER1  = 1'b0;
                rLER2  = 1'b0;
                rLER3  = 1'b1;                  
                rLEPC  = 1'b0;
              end

          2 : begin                             // R2
                rLER0  = 1'b0;
                rLER1  = 1'b0;
                rLER2  = 1'b1;                  
                rLER3  = 1'b0;
                rLEPC  = 1'b0;
              end

          1 : begin                             // R1
                rLER0  = 1'b0;
                rLER1  = 1'b1;                  
                rLER2  = 1'b0;
                rLER3  = 1'b0;
                rLEPC  = 1'b0;
              end

          0 : begin                             // R0
                rLER0  = 1'b1;                  
                rLER1  = 1'b0;
                rLER2  = 1'b0;
                rLER3  = 1'b0;
                rLEPC  = 1'b0;
              end

         
        endcase

        assign oSel       = rIR[15:13];         // pass-through.
        assign oLER0      = rLER0 & !iSquelch;  // decode iIR[12:10].
        assign oLER1      = rLER1 & !iSquelch;  // decode iIR[12:10].
        assign oLER2      = rLER2 & !iSquelch;  // decode iIR[12:10].
        assign oLER3      = rLER3 & !iSquelch;  // decode iIR[12:10].
        assign oLEPC      = rLEPC & !iSquelch;  // decode iIR[12:10].
        assign oWE        = rIR[9] & !iSquelch; // pass-through.
        assign oCEPC      = rIR[8] & !iSquelch; // pass-through.
        assign oImmediate = rIR[7:0];           // pass-through.


        always @ (iIR or iBypass or iBypassIR)
        if (iBypassIR) rIR = iBypass;
        else rIR = iIR;
/*-------------------------------*/endmodule/*--------------------------------*/