Mike Moore
/
RTOS_project_fork_01
embedded RTOS class project.
Fork of RTOS_project by
mmRTL/instruction_decoder.txt
- Committer:
- gatedClock
- Date:
- 2013-09-17
- Revision:
- 4:e3887e314551
- Parent:
- 0:8e898e1270d6
File content as of revision 4:e3887e314551:
/*----------------------------------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/*--------------------------------*/