Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: C12832_lcd USBDevice mbed-rtos mbed mmSPI_RTOS watchdog_RTOS
mmRTL/cpu.txt
- Committer:
- gatedClock
- Date:
- 2013-09-17
- Revision:
- 0:8e898e1270d6
File content as of revision 0:8e898e1270d6:
/*----------------------------------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/*--------------------------------*/