Add SAP-3
This commit is contained in:
parent
eb7cc9dc79
commit
3c0263fc05
|
@ -1,9 +1,13 @@
|
|||
# FPGA Computer
|
||||
|
||||
8-bit computer modeled after the SAP-1 from the book [Digital Computer
|
||||
8-bit computer modeled after the Simple-As-Possible computers from the book [Digital Computer
|
||||
Electronics](https://www.goodreads.com/book/show/942643.Digital_Computer_Electronics) by Malvino and
|
||||
Brown.
|
||||
|
||||
The SAP-3 is the final iteration of the computer and shares an instruction set with the Intel
|
||||
8080/8085, minus a few instructions.
|
||||
|
||||
* [Blog post about the SAP-1.](https://austinmorlan.com/posts/fpga_computer_sap1/)
|
||||
* [Blog post about the SAP-2.](https://austinmorlan.com/posts/fpga_computer_sap2/)
|
||||
* [Blog post about the SAP-3.](https://austinmorlan.com/posts/fpga_computer_sap3/)
|
||||
|
||||
|
|
40
build.sh
40
build.sh
|
@ -35,6 +35,17 @@ SAP2_MODULES="
|
|||
SAP2_TOP=$SRC_DIR/sap2/top.v
|
||||
SAP2_TB=$SRC_DIR/sap2/top_tb.v
|
||||
|
||||
SAP3_MODULES="
|
||||
$SRC_DIR/sap3/alu.v
|
||||
$SRC_DIR/sap3/clock.v
|
||||
$SRC_DIR/sap3/controller.v
|
||||
$SRC_DIR/sap3/ir.v
|
||||
$SRC_DIR/sap3/memory.v
|
||||
$SRC_DIR/sap3/reg_file.v"
|
||||
|
||||
SAP3_TOP=$SRC_DIR/sap3/top.v
|
||||
SAP3_TB=$SRC_DIR/sap3/top_tb.v
|
||||
|
||||
|
||||
if [ -z "$COMMAND" ]; then
|
||||
mkdir -p $BUILD_DIR/sap1
|
||||
|
@ -54,6 +65,15 @@ if [ -z "$COMMAND" ]; then
|
|||
$BIN_DIR/icepack hardware.asc hardware.bin
|
||||
|
||||
popd > /dev/null
|
||||
|
||||
mkdir -p $BUILD_DIR/sap3
|
||||
pushd $BUILD_DIR/sap3 > /dev/null
|
||||
|
||||
$BIN_DIR/yosys -p "synth_ice40 -json hardware.json" $SAP3_MODULES $SAP3_TOP
|
||||
$BIN_DIR/nextpnr-ice40 --lp8k --package cm81 --json hardware.json --asc hardware.asc --pcf $SRC_DIR/pins.pcf -q
|
||||
$BIN_DIR/icepack hardware.asc hardware.bin
|
||||
|
||||
popd > /dev/null
|
||||
elif [ "$COMMAND" == "init" ]; then
|
||||
virtualenv .env
|
||||
source .env/bin/activate
|
||||
|
@ -70,13 +90,14 @@ elif [ "$COMMAND" == "program" ]; then
|
|||
exit 1
|
||||
elif [ "$VERSION" == "sap1" ]; then
|
||||
pushd $BUILD_DIR/sap1 > /dev/null
|
||||
sudo tinyprog -p hardware.bin
|
||||
popd > /dev/null
|
||||
elif [ "$VERSION" == "sap2" ]; then
|
||||
pushd $BUILD_DIR/sap2 > /dev/null
|
||||
sudo tinyprog -p hardware.bin
|
||||
popd > /dev/null
|
||||
elif [ "$VERSION" == "sap3" ]; then
|
||||
pushd $BUILD_DIR/sap3 > /dev/null
|
||||
fi
|
||||
|
||||
sudo tinyprog -p hardware.bin
|
||||
popd > /dev/null
|
||||
elif [ "$COMMAND" == "sim" ]; then
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "sim needs a version"
|
||||
|
@ -101,8 +122,17 @@ elif [ "$COMMAND" == "sim" ]; then
|
|||
popd > /dev/null
|
||||
|
||||
gtkwave $BUILD_DIR/sap2/top_tb.vcd $BUILD_DIR/sap2/top_tb.gtkw
|
||||
fi
|
||||
elif [ "$VERSION" == "sap3" ]; then
|
||||
mkdir -p $BUILD_DIR/sap3
|
||||
|
||||
pushd $SRC_DIR/sap3 > /dev/null
|
||||
$BIN_DIR/iverilog -o $BUILD_DIR/sap3/top_tb $SAP3_MODULES $SAP3_TB
|
||||
$BIN_DIR/vvp $BUILD_DIR/sap3/top_tb
|
||||
mv top_tb.vcd $BUILD_DIR/sap3
|
||||
popd > /dev/null
|
||||
|
||||
gtkwave $BUILD_DIR/sap3/top_tb.vcd $BUILD_DIR/sap3/top_tb.gtkw
|
||||
fi
|
||||
else
|
||||
echo "Invalid arguments"
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
module alu(
|
||||
input clk,
|
||||
input rst,
|
||||
input cs,
|
||||
input flags_we,
|
||||
input a_we,
|
||||
input a_store,
|
||||
input a_restore,
|
||||
input tmp_we,
|
||||
input[4:0] op,
|
||||
input[7:0] bus,
|
||||
output[7:0] flags,
|
||||
output[7:0] out
|
||||
);
|
||||
|
||||
reg carry;
|
||||
|
||||
wire flg_c;
|
||||
wire flg_z;
|
||||
wire flg_p;
|
||||
wire flg_s;
|
||||
|
||||
reg[7:0] acc;
|
||||
reg[7:0] flg;
|
||||
reg[7:0] act; // Internal
|
||||
reg[7:0] tmp; // Internal
|
||||
|
||||
localparam FLG_Z = 0;
|
||||
localparam FLG_C = 1;
|
||||
localparam FLG_P = 2;
|
||||
localparam FLG_S = 3;
|
||||
|
||||
localparam OP_ADD = 5'b00000;
|
||||
localparam OP_ADC = 5'b00001;
|
||||
localparam OP_SUB = 5'b00010;
|
||||
localparam OP_SBB = 5'b00011;
|
||||
localparam OP_ANA = 5'b00100;
|
||||
localparam OP_XRA = 5'b00101;
|
||||
localparam OP_ORA = 5'b00110;
|
||||
localparam OP_CMP = 5'b00111;
|
||||
localparam OP_RLC = 5'b01000;
|
||||
localparam OP_RRC = 5'b01001;
|
||||
localparam OP_RAL = 5'b01010;
|
||||
localparam OP_RAR = 5'b01011;
|
||||
localparam OP_DAA = 5'b01100; // Unsupported
|
||||
localparam OP_CMA = 5'b01101;
|
||||
localparam OP_STC = 5'b01110;
|
||||
localparam OP_CMC = 5'b01111;
|
||||
localparam OP_INR = 5'b10000;
|
||||
localparam OP_DCR = 5'b10001;
|
||||
|
||||
assign flg_c = (carry == 1'b1);
|
||||
assign flg_z = (acc[7:0] == 8'b0);
|
||||
assign flg_s = acc[7];
|
||||
assign flg_p = ~^acc[7:0];
|
||||
|
||||
always @(posedge clk, posedge rst) begin
|
||||
if (rst) begin
|
||||
acc <= 8'b0;
|
||||
act <= 8'b0;
|
||||
tmp <= 8'b0;
|
||||
carry <= 1'b0;
|
||||
end else begin
|
||||
if (a_we) begin
|
||||
acc <= bus;
|
||||
end else if (a_restore) begin
|
||||
acc <= act;
|
||||
end else if (cs) begin
|
||||
case (op)
|
||||
OP_ADD: begin
|
||||
{carry, acc} <= acc + tmp;
|
||||
end
|
||||
OP_ADC: begin
|
||||
{carry, acc} <= acc + tmp + flg[FLG_C];
|
||||
end
|
||||
OP_SUB: begin
|
||||
{carry, acc} <= acc - tmp;
|
||||
end
|
||||
OP_SBB: begin
|
||||
{carry, acc} <= acc - tmp - flg[FLG_C];
|
||||
end
|
||||
OP_ANA: begin
|
||||
{carry, acc} <= acc & tmp;
|
||||
end
|
||||
OP_XRA: begin
|
||||
{carry, acc} <= acc ^ tmp;
|
||||
end
|
||||
OP_ORA: begin
|
||||
{carry, acc} <= acc | tmp;
|
||||
end
|
||||
OP_CMP: begin
|
||||
act <= acc - tmp;
|
||||
end
|
||||
OP_RLC: begin
|
||||
carry <= acc[7];
|
||||
acc <= acc << 1;
|
||||
end
|
||||
OP_RRC: begin
|
||||
carry <= acc[0];
|
||||
acc <= acc >> 1;
|
||||
end
|
||||
OP_RAL: begin
|
||||
carry <= acc[7];
|
||||
acc <= (acc << 1 | {7'b0, flg[FLG_C]});
|
||||
end
|
||||
OP_RAR: begin
|
||||
carry <= acc[0];
|
||||
acc <= (acc >> 1 | {flg[FLG_C], 7'b0});
|
||||
end
|
||||
OP_CMA: begin
|
||||
acc <= ~acc;
|
||||
end
|
||||
OP_STC: begin
|
||||
carry <= 1'b1;
|
||||
end
|
||||
OP_CMC: begin
|
||||
carry <= ~flg[FLG_C];
|
||||
end
|
||||
OP_INR: begin
|
||||
acc <= acc + 1;
|
||||
end
|
||||
OP_DCR: begin
|
||||
acc <= acc - 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (a_store)
|
||||
act <= acc;
|
||||
|
||||
if (tmp_we)
|
||||
tmp <= bus;
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge clk, posedge rst) begin
|
||||
if (rst) begin
|
||||
flg <= 8'b0;
|
||||
end else if (flags_we) begin
|
||||
flg <= bus;
|
||||
end else begin
|
||||
if (cs) begin
|
||||
case (op)
|
||||
OP_ADD, OP_ADC, OP_SUB, OP_SBB, OP_ANA, OP_XRA, OP_ORA: begin
|
||||
flg[FLG_C] <= flg_c;
|
||||
flg[FLG_Z] <= flg_z;
|
||||
flg[FLG_S] <= flg_s;
|
||||
flg[FLG_P] <= flg_p;
|
||||
end
|
||||
|
||||
OP_CMP: begin
|
||||
flg[FLG_Z] <= (act == 8'b0);
|
||||
end
|
||||
|
||||
OP_INR, OP_DCR: begin
|
||||
flg[FLG_Z] <= flg_z;
|
||||
flg[FLG_S] <= flg_s;
|
||||
flg[FLG_P] <= flg_p;
|
||||
end
|
||||
|
||||
OP_RLC, OP_RRC, OP_RAL, OP_RAR, OP_STC, OP_CMC: begin
|
||||
flg[FLG_C] <= flg_c;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign flags = flg;
|
||||
assign out = acc;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
module clock(
|
||||
input hlt,
|
||||
input clk_in,
|
||||
output clk_out);
|
||||
|
||||
assign clk_out = (hlt) ? 1'b0 : clk_in;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,928 @@
|
|||
module controller(
|
||||
input clk,
|
||||
input rst,
|
||||
input[7:0] opcode,
|
||||
input[7:0] flags,
|
||||
output[32:0] out
|
||||
);
|
||||
|
||||
localparam DISPLAY = 32;
|
||||
localparam HLT = 31;
|
||||
localparam ALU_CS = 30;
|
||||
localparam ALU_FLAGS_WE = 29;
|
||||
localparam ALU_A_WE = 28;
|
||||
localparam ALU_A_STORE = 27;
|
||||
localparam ALU_A_RESTORE = 26;
|
||||
localparam ALU_TMP_WE = 25;
|
||||
localparam ALU_OP4 = 24;
|
||||
localparam ALU_OP0 = 20;
|
||||
localparam ALU_OE = 19;
|
||||
localparam ALU_FLAGS_OE = 18;
|
||||
localparam REG_RD_SEL4 = 17;
|
||||
localparam REG_RD_SEL0 = 13;
|
||||
localparam REG_WR_SEL4 = 12;
|
||||
localparam REG_WR_SEL0 = 8;
|
||||
localparam REG_EXT1 = 7;
|
||||
localparam REG_EXT0 = 6;
|
||||
localparam REG_OE = 5;
|
||||
localparam REG_WE = 4;
|
||||
localparam MEM_WE = 3;
|
||||
localparam MEM_MAR_WE = 2;
|
||||
localparam MEM_OE = 1;
|
||||
localparam IR_WE = 0;
|
||||
|
||||
localparam REG_INC = 2'b01;
|
||||
localparam REG_DEC = 2'b10;
|
||||
localparam REG_INC2 = 2'b11;
|
||||
|
||||
localparam REG_BC = 5'b10000;
|
||||
localparam REG_BC_B = 5'b00000;
|
||||
localparam REG_BC_C = 5'b00001;
|
||||
|
||||
localparam REG_DE = 5'b10010;
|
||||
localparam REG_DE_D = 5'b00010;
|
||||
localparam REG_DE_E = 5'b00011;
|
||||
|
||||
localparam REG_HL = 5'b10100;
|
||||
localparam REG_HL_H = 5'b00100;
|
||||
localparam REG_HL_L = 5'b00101;
|
||||
|
||||
localparam REG_WZ = 5'b10110;
|
||||
localparam REG_WZ_W = 5'b00110;
|
||||
localparam REG_WZ_Z = 5'b00111;
|
||||
|
||||
localparam REG_PC = 5'b11000;
|
||||
localparam REG_PC_P = 5'b01000;
|
||||
localparam REG_PC_C = 5'b01001;
|
||||
|
||||
localparam REG_SP = 5'b11010;
|
||||
localparam REG_SP_S = 5'b01010;
|
||||
localparam REG_SP_P = 5'b01011;
|
||||
|
||||
reg[32:0] ctrl_word;
|
||||
reg[3:0] stage;
|
||||
reg stage_rst;
|
||||
|
||||
assign out = ctrl_word;
|
||||
|
||||
always @(negedge clk, posedge rst) begin
|
||||
if (rst) begin
|
||||
stage <= 0;
|
||||
end else begin
|
||||
if (stage_rst) begin
|
||||
stage <= 0;
|
||||
end else begin
|
||||
stage <= stage + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
ctrl_word = 0;
|
||||
stage_rst = 0;
|
||||
|
||||
if (stage == 0) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 1) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[IR_WE] = 1'b1;
|
||||
end else if (stage == 2) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else begin
|
||||
casez (opcode)
|
||||
// NOP
|
||||
8'o000: begin
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
|
||||
// HLT
|
||||
8'o166: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[HLT] = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// MOV Rd, M
|
||||
// opcode[5:3] - Rd
|
||||
8'o1?6: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
if (opcode[5:3] == 3'b111) begin
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// MOV M, Rs
|
||||
// opcode[2:0] - Rs
|
||||
8'o16?: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
if (opcode[2:0] == 3'b111) begin
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// MOV Rd, Rs
|
||||
// opcode[5:3] - Rd
|
||||
// opcode[2:0] - Rs
|
||||
8'o1??: begin
|
||||
if (stage == 3) begin
|
||||
if (opcode[2:0] == 3'b111) begin
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
end
|
||||
|
||||
if (opcode[5:3] == 3'b111) begin
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end
|
||||
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// INX, DCX
|
||||
// opcode[5:4] - 16-bit Register
|
||||
// opcode[3] - Dec(1) / Inc (0)
|
||||
8'o0?3: begin
|
||||
if (stage == 3) begin
|
||||
if (opcode[5:4] == 2'b11)
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
else
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b10, opcode[5:4], 1'b0};
|
||||
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = {opcode[3], ~opcode[3]};
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// INR/DCR M
|
||||
// opcode[5:3] - Rs
|
||||
// opcode[0] - INR (0), DCR (1)
|
||||
8'o064: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[ALU_A_STORE] = 1'b1;
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = {4'b1000, opcode[0]};
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
ctrl_word[ALU_A_RESTORE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// INR/DCR Rs
|
||||
// opcode[5:3] - Rs
|
||||
// opcode[0] - INR (0), DCR (1)
|
||||
8'o0?4, 8'o0?5: begin
|
||||
if (stage == 3) begin
|
||||
if (opcode[5:3] == 3'b111) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = 5'b10000;
|
||||
stage_rst = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:3]};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[ALU_A_STORE] = 1'b1;
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = {4'b1000, opcode[0]};
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
ctrl_word[ALU_A_RESTORE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Arithmetic/Logic Set 0 (M)
|
||||
// opcode[5:3] - ALU Op
|
||||
8'o2?6: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[ALU_TMP_WE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Arithmetic/Logic Set 0
|
||||
// opcode[2:0] - Rs
|
||||
// opcode[5:3] - ALU Op
|
||||
8'o2??: begin
|
||||
if (stage == 3) begin
|
||||
if (opcode[2:0] == 3'b111) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
|
||||
stage_rst = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[ALU_TMP_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Arithmetic/Logic Set 1
|
||||
// opcode[5:3] - ALU Op
|
||||
8'o0?7: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = {2'b01, opcode[5:3]};
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Arithmetic/Logic Immediate
|
||||
// opcode[5:3] - ALU Op
|
||||
8'o3?6: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[ALU_TMP_WE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// MVI M, d8
|
||||
8'o066: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, REG_WZ_W};
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, REG_WZ_W};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// MVI Rd, d8
|
||||
// opcode[5:3] - Rd
|
||||
8'o0?6: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
if (opcode[5:3] == 3'b111) begin
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// LXI
|
||||
// opcode[5:4] - Extended Register
|
||||
8'o001, 8'o021, 8'o041, 8'o061: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
end else if (stage == 8) begin
|
||||
if (opcode[5:4] == 2'b11)
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
else
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b10, opcode[5:4], 1'b0};
|
||||
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// LDA/STA a16
|
||||
// opcode[3]: STA (0) / LDA (1)
|
||||
8'o062, 8'o072: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 10) begin
|
||||
if (opcode[3] == 0) begin
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end
|
||||
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// STAX/LDAX Rs
|
||||
// opcode[5:4] - Rs
|
||||
// opcode[3] - STAX (0) / LDAX (1)
|
||||
8'o002, 8'o012, 8'o022, 8'o032: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
if (opcode[3] == 1'b0) begin
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end
|
||||
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// SHLD, LHLD
|
||||
// opcode[3] - SHLD (0) / LHLD (1)
|
||||
8'o042, 8'o052: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 10) begin
|
||||
if (opcode[3] == 1'b0) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_H;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL_H;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end
|
||||
end else if (stage == 11) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 12) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 13) begin
|
||||
if (opcode[3] == 1'b0) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_L;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL_L;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end
|
||||
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// DAD
|
||||
// opcode[5:4] - Extended Register
|
||||
8'o011, 8'o031, 8'o051, 8'o071: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_L;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[ALU_A_STORE] = 1'b1;
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
if (opcode[5:4] == 2'b11) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP_P;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
|
||||
end
|
||||
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[ALU_TMP_WE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = 5'b00000; // Add
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_H;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
if (opcode[5:4] == 2'b11) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP_S;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
|
||||
end
|
||||
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[ALU_TMP_WE] = 1'b1;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[ALU_CS] = 1'b1;
|
||||
ctrl_word[ALU_OP4:ALU_OP0] = 5'b00001; // Add w/ Carry
|
||||
end else if (stage == 10) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
ctrl_word[ALU_A_RESTORE] = 1'b1;
|
||||
end else if (stage == 11) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// JMP
|
||||
8'o303: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Jump Conditional
|
||||
// opcode[5:4] - flag
|
||||
// opcode[3] - set (1) / unset (0)
|
||||
8'o3?2: begin
|
||||
if (stage == 3) begin
|
||||
if (flags[opcode[5:4]] != opcode[3]) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC2;
|
||||
stage_rst = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Call Conditional
|
||||
// opcode[5:4] - flag
|
||||
// opcode[3] - set (1) / unset (0)
|
||||
8'o3?4: begin
|
||||
if (stage == 3) begin
|
||||
if (flags[opcode[5:4]] != opcode[3]) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC2;
|
||||
stage_rst = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
|
||||
end else if (stage == 10) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 11) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_C;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else if (stage == 12) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
|
||||
end else if (stage == 13) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 14) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_P;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else if (stage == 15) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// CALL
|
||||
8'o315: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
|
||||
end else if (stage == 10) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 11) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_C;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else if (stage == 12) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
|
||||
end else if (stage == 13) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 14) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_P;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else if (stage == 15) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Return Conditional
|
||||
// opcode[5:4] - flag
|
||||
// opcode[3] - set (1) / unset (0)
|
||||
8'o3?0: begin
|
||||
if (stage == 3) begin
|
||||
if (flags[opcode[5:4]] != opcode[3]) begin
|
||||
stage_rst = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// RET
|
||||
8'o311: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 9) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// PUSH Rs
|
||||
// opcode[5:4] - Extended Register
|
||||
8'o3?5: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
|
||||
end else if (stage == 4) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
if (opcode[5:4] == 2'b11) begin // PSW
|
||||
ctrl_word[ALU_OE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
|
||||
end else if (stage == 7) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
if (opcode[5:4] == 2'b11) begin // PSW
|
||||
ctrl_word[ALU_FLAGS_OE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[MEM_WE] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// POP Rs
|
||||
// opcode[5:4] - Extended Register
|
||||
8'o301, 8'o321, 8'o341, 8'o361: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 4) begin
|
||||
if (opcode[5:4] == 2'b11) begin // PSW
|
||||
ctrl_word[ALU_FLAGS_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:4], 1'b1};
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 5) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
end else if (stage == 6) begin
|
||||
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
|
||||
ctrl_word[REG_OE] = 1'b1;
|
||||
ctrl_word[MEM_MAR_WE] = 1'b1;
|
||||
end else if (stage == 7) begin
|
||||
if (opcode[5:4] == 2'b11) begin // PSW
|
||||
ctrl_word[ALU_A_WE] = 1'b1;
|
||||
end else begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:4], 1'b0};
|
||||
ctrl_word[REG_WE] = 1'b1;
|
||||
end
|
||||
|
||||
ctrl_word[MEM_OE] = 1'b1;
|
||||
end else if (stage == 8) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// OUT
|
||||
8'o323: begin
|
||||
if (stage == 3) begin
|
||||
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
|
||||
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
|
||||
ctrl_word[DISPLAY] = 1'b1;
|
||||
stage_rst = 1'b1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
module ir(
|
||||
input clk,
|
||||
input rst,
|
||||
input we,
|
||||
input[7:0] bus,
|
||||
output[7:0] out
|
||||
);
|
||||
|
||||
reg[7:0] ir;
|
||||
|
||||
always @(posedge clk, posedge rst) begin
|
||||
if (rst) begin
|
||||
ir <= 8'b0;
|
||||
end else if (we) begin
|
||||
ir <= bus;
|
||||
end
|
||||
end
|
||||
|
||||
assign out = ir;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
module memory(
|
||||
input clk,
|
||||
input rst,
|
||||
input mar_we,
|
||||
input ram_we,
|
||||
input[15:0] bus,
|
||||
output[7:0] out
|
||||
);
|
||||
|
||||
initial begin
|
||||
$readmemh("program.bin", ram);
|
||||
end
|
||||
|
||||
reg[15:0] mar;
|
||||
reg[7:0] ram[0:255];
|
||||
|
||||
always @(posedge clk, posedge rst) begin
|
||||
if (rst)
|
||||
mar <= 16'b0;
|
||||
else if (mar_we)
|
||||
mar <= bus;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ram_we)
|
||||
ram[mar] <= bus[7:0];
|
||||
end
|
||||
|
||||
assign out = ram[mar];
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
31 f0 00 3e 01 06 00 d3
|
||||
ff 4f 78 fe 01 79 ca 17
|
||||
00 c2 20 00 c3 07 00 1f
|
||||
fe 01 cc 29 00 c3 07 00
|
||||
17 fe 80 cc 2c 00 c3 07
|
||||
00 06 00 c9 06 01 c9 76
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
|
@ -0,0 +1,72 @@
|
|||
module reg_file(
|
||||
input clk,
|
||||
input rst,
|
||||
input[4:0] rd_sel,
|
||||
input[4:0] wr_sel,
|
||||
input[1:0] ext,
|
||||
input we,
|
||||
input[15:0] data_in,
|
||||
output[15:0] data_out
|
||||
);
|
||||
|
||||
// 8-bit
|
||||
// 0 1
|
||||
// 0000_ [ B ][ C ]
|
||||
// 0001_ [ D ][ E ]
|
||||
// 0010_ [ H ][ L ]
|
||||
// 0011_ [ W ][ Z ]
|
||||
// 0100_ [ P ][ C ]
|
||||
// 0101_ [ S ][ P ]
|
||||
|
||||
// 16-bit (ext)
|
||||
//
|
||||
// 10000 [ BC ]
|
||||
// 10010 [ DE ]
|
||||
// 10100 [ HL ]
|
||||
// 10110 [ WZ ]
|
||||
// 11000 [ PC ]
|
||||
// 11010 [ SP ]
|
||||
reg[7:0] data[0:11];
|
||||
|
||||
reg[15:0] data_out;
|
||||
wire wr_ext = wr_sel[4];
|
||||
wire rd_ext = rd_sel[4];
|
||||
wire[3:0] wr_dst = wr_sel[3:0];
|
||||
wire[3:0] rd_src = rd_sel[3:0];
|
||||
|
||||
localparam EXT_INC = 2'b01;
|
||||
localparam EXT_DEC = 2'b10;
|
||||
localparam EXT_INC2 = 2'b11;
|
||||
|
||||
always @(posedge clk, posedge rst) begin
|
||||
if (rst) begin
|
||||
data[0] <= 8'b0; data[1] <= 8'b0; data[2] <= 8'b0; data[3] <= 8'b0; data[4] <= 8'b0;
|
||||
data[5] <= 8'b0; data[6] <= 8'b0; data[7] <= 8'b0; data[8] <= 8'b0; data[9] <= 8'b0;
|
||||
data[10] <= 8'b0; data[11] <= 8'b0;
|
||||
end else begin
|
||||
if (ext == EXT_INC) begin
|
||||
{data[wr_dst], data[wr_dst+1]} <= {data[wr_dst], data[wr_dst+1]} + 1;
|
||||
end else if (ext == EXT_INC2) begin
|
||||
{data[wr_dst], data[wr_dst+1]} <= {data[wr_dst], data[wr_dst+1]} + 2;
|
||||
end else if (ext == EXT_DEC) begin
|
||||
{data[wr_dst], data[wr_dst+1]} <= {data[wr_dst], data[wr_dst+1]} - 1;
|
||||
end else if (we) begin
|
||||
if (wr_ext) begin
|
||||
{data[wr_dst], data[wr_dst+1]} <= data_in;
|
||||
end else begin
|
||||
data[wr_dst] <= data_in[7:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
if (rd_ext) begin
|
||||
data_out = {data[rd_src], data[rd_src+1]};
|
||||
end else begin
|
||||
data_out = {8'b0, data[rd_src]};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
module top(
|
||||
input CLK,
|
||||
input PIN_24,
|
||||
output PIN_4,
|
||||
output PIN_5,
|
||||
output PIN_6,
|
||||
output PIN_7,
|
||||
output PIN_8,
|
||||
output PIN_9,
|
||||
output PIN_10,
|
||||
output PIN_11,
|
||||
);
|
||||
|
||||
|
||||
assign rst = PIN_24;
|
||||
assign {PIN_4, PIN_5, PIN_6, PIN_7, PIN_8, PIN_9, PIN_10, PIN_11} = out;
|
||||
|
||||
reg[7:0] out;
|
||||
always @(posedge clk, posedge rst) begin
|
||||
if (rst) begin
|
||||
out = 8'b0;
|
||||
end else if (display) begin
|
||||
out = alu_out;
|
||||
end
|
||||
end
|
||||
|
||||
reg[18:0] bus;
|
||||
|
||||
always @(*) begin
|
||||
bus = 16'b0;
|
||||
|
||||
if (reg_oe)
|
||||
bus = reg_out;
|
||||
else if (mem_oe)
|
||||
bus = {8'b0, mem_out};
|
||||
else if (alu_oe)
|
||||
bus = {8'b0, alu_out};
|
||||
else if (alu_flags_oe)
|
||||
bus = {8'b0, alu_flags};
|
||||
end
|
||||
|
||||
reg[23:0] clk_slow;
|
||||
always @(posedge CLK) begin
|
||||
clk_slow <= clk_slow + 1;
|
||||
end
|
||||
|
||||
wire rst;
|
||||
wire hlt;
|
||||
wire clk;
|
||||
clock clock(
|
||||
.hlt(hlt),
|
||||
.clk_in(clk_slow[14]),
|
||||
.clk_out(clk)
|
||||
);
|
||||
|
||||
wire[4:0] reg_rd_sel;
|
||||
wire[4:0] reg_wr_sel;
|
||||
wire[1:0] reg_ext;
|
||||
wire reg_oe;
|
||||
wire reg_we;
|
||||
wire[15:0] reg_out;
|
||||
reg_file reg_file(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.rd_sel(reg_rd_sel),
|
||||
.wr_sel(reg_wr_sel),
|
||||
.ext(reg_ext),
|
||||
.we(reg_we),
|
||||
.data_in(bus),
|
||||
.data_out(reg_out)
|
||||
);
|
||||
|
||||
wire mem_mar_we;
|
||||
wire mem_ram_we;
|
||||
wire mem_oe;
|
||||
wire[7:0] mem_out;
|
||||
memory memory(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.mar_we(mem_mar_we),
|
||||
.ram_we(mem_ram_we),
|
||||
.bus(bus),
|
||||
.out(mem_out)
|
||||
);
|
||||
|
||||
wire ir_we;
|
||||
wire[7:0] ir_out;
|
||||
ir ir(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.we(ir_we),
|
||||
.bus(bus[7:0]),
|
||||
.out(ir_out)
|
||||
);
|
||||
|
||||
wire alu_cs;
|
||||
wire alu_flags_we;
|
||||
wire alu_a_we;
|
||||
wire alu_a_store;
|
||||
wire alu_a_restore;
|
||||
wire alu_tmp_we;
|
||||
wire alu_oe;
|
||||
wire alu_flags_oe;
|
||||
wire[4:0] alu_op;
|
||||
wire[7:0] alu_flags;
|
||||
wire[7:0] alu_out;
|
||||
alu alu(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.cs(alu_cs),
|
||||
.flags_we(alu_flags_we),
|
||||
.a_we(alu_a_we),
|
||||
.a_store(alu_a_store),
|
||||
.a_restore(alu_a_restore),
|
||||
.tmp_we(alu_tmp_we),
|
||||
.op(alu_op),
|
||||
.bus(bus[7:0]),
|
||||
.flags(alu_flags),
|
||||
.out(alu_out)
|
||||
);
|
||||
|
||||
wire display;
|
||||
controller controller(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.opcode(ir_out),
|
||||
.flags(alu_flags),
|
||||
.out({
|
||||
display,
|
||||
hlt,
|
||||
alu_cs,
|
||||
alu_flags_we,
|
||||
alu_a_we,
|
||||
alu_a_store,
|
||||
alu_a_restore,
|
||||
alu_tmp_we,
|
||||
alu_op,
|
||||
alu_oe,
|
||||
alu_flags_oe,
|
||||
reg_rd_sel,
|
||||
reg_wr_sel,
|
||||
reg_ext,
|
||||
reg_oe,
|
||||
reg_we,
|
||||
mem_ram_we,
|
||||
mem_mar_we,
|
||||
mem_oe,
|
||||
ir_we
|
||||
})
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
module top_tb();
|
||||
|
||||
|
||||
initial begin
|
||||
$dumpfile("top_tb.vcd");
|
||||
$dumpvars(0, top_tb);
|
||||
for (i = 0; i < 12; i++) begin
|
||||
$dumpvars(0, reg_file.data[i]);
|
||||
end
|
||||
for (i = 230; i < 256; i++) begin
|
||||
$dumpvars(0, memory.ram[i]);
|
||||
end
|
||||
rst = 1;
|
||||
#1 rst = 0;
|
||||
end
|
||||
|
||||
reg clk_in = 0;
|
||||
integer i;
|
||||
initial begin
|
||||
for (i = 0; i < 8096; i++) begin
|
||||
#1 clk_in = ~clk_in;
|
||||
end
|
||||
end
|
||||
|
||||
reg[7:0] out;
|
||||
always @(posedge clk, posedge rst) begin
|
||||
if (rst) begin
|
||||
out = 8'b0;
|
||||
end else if (display) begin
|
||||
out = alu_out;
|
||||
end
|
||||
end
|
||||
|
||||
reg[15:0] bus;
|
||||
|
||||
always @(*) begin
|
||||
bus = 16'b0;
|
||||
|
||||
if (reg_oe)
|
||||
bus = reg_out;
|
||||
else if (mem_oe)
|
||||
bus = {8'b0, mem_out};
|
||||
else if (alu_oe)
|
||||
bus = {8'b0, alu_out};
|
||||
else if (alu_flags_oe)
|
||||
bus = {8'b0, alu_flags};
|
||||
end
|
||||
|
||||
reg rst;
|
||||
wire hlt;
|
||||
wire clk;
|
||||
clock clock(
|
||||
.hlt(hlt),
|
||||
.clk_in(clk_in),
|
||||
.clk_out(clk)
|
||||
);
|
||||
|
||||
wire[4:0] reg_rd_sel;
|
||||
wire[4:0] reg_wr_sel;
|
||||
wire[1:0] reg_ext;
|
||||
wire reg_oe;
|
||||
wire reg_we;
|
||||
wire[15:0] reg_out;
|
||||
reg_file reg_file(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.rd_sel(reg_rd_sel),
|
||||
.wr_sel(reg_wr_sel),
|
||||
.ext(reg_ext),
|
||||
.we(reg_we),
|
||||
.data_in(bus),
|
||||
.data_out(reg_out)
|
||||
);
|
||||
|
||||
wire mem_mar_we;
|
||||
wire mem_ram_we;
|
||||
wire mem_oe;
|
||||
wire[7:0] mem_out;
|
||||
memory memory(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.mar_we(mem_mar_we),
|
||||
.ram_we(mem_ram_we),
|
||||
.bus(bus),
|
||||
.out(mem_out)
|
||||
);
|
||||
|
||||
wire ir_we;
|
||||
wire[7:0] ir_out;
|
||||
ir ir(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.we(ir_we),
|
||||
.bus(bus[7:0]),
|
||||
.out(ir_out)
|
||||
);
|
||||
|
||||
wire alu_cs;
|
||||
wire alu_flags_we;
|
||||
wire alu_a_we;
|
||||
wire alu_a_store;
|
||||
wire alu_a_restore;
|
||||
wire alu_tmp_we;
|
||||
wire alu_oe;
|
||||
wire alu_flags_oe;
|
||||
wire[4:0] alu_op;
|
||||
wire[7:0] alu_flags;
|
||||
wire[7:0] alu_out;
|
||||
alu alu(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.cs(alu_cs),
|
||||
.flags_we(alu_flags_we),
|
||||
.a_we(alu_a_we),
|
||||
.a_store(alu_a_store),
|
||||
.a_restore(alu_a_restore),
|
||||
.tmp_we(alu_tmp_we),
|
||||
.op(alu_op),
|
||||
.bus(bus[7:0]),
|
||||
.flags(alu_flags),
|
||||
.out(alu_out)
|
||||
);
|
||||
|
||||
controller controller(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.opcode(ir_out),
|
||||
.flags(alu_flags),
|
||||
.out({
|
||||
display,
|
||||
hlt,
|
||||
alu_cs,
|
||||
alu_flags_we,
|
||||
alu_a_we,
|
||||
alu_a_store,
|
||||
alu_a_restore,
|
||||
alu_tmp_we,
|
||||
alu_op,
|
||||
alu_oe,
|
||||
alu_flags_oe,
|
||||
reg_rd_sel,
|
||||
reg_wr_sel,
|
||||
reg_ext,
|
||||
reg_oe,
|
||||
reg_we,
|
||||
mem_ram_we,
|
||||
mem_mar_we,
|
||||
mem_oe,
|
||||
ir_we
|
||||
})
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue