diff --git a/modules/assignment3.sv b/modules/assignment3.sv new file mode 100644 index 0000000..723e1ca --- /dev/null +++ b/modules/assignment3.sv @@ -0,0 +1,107 @@ +`ifndef ASS_3_SV +`define ASS_3_SV + +`include "rom.sv" +`include "ram.sv" +`include "register_file.sv" +`include "instruction_counter.sv" +`include "control_unit.sv" +`include "alu.sv" +`include "shifter.sv" +`include "sign_extender.sv" +`include "gatereg.sv" + +`ifdef QUARTUS_SYNTH +`include "seven_seg_4digit.sv" +`endif + +module assignment3 #(width, romsz, ramsz)( + input logic [0:0] clk, input logic [0:0] rst, +`ifdef QUARTUS_SYNTH + , + input logic [4:0] HID_Register, + input logic [0:0] HID_PC, + input logic [0:0] HID_Hi_Low, + + output logic[7:0] out_seg_0, + output logic[7:0] out_seg_1, + output logic[7:0] out_seg_2, + output logic[7:0] out_seg_3 +`endif +); + logic [2**width-1:0] pc_addr, pc_addr_2; + logic [2**width-1:0] pc_addr_write; + logic [0:0] pc_we; + // TODO: Verify if we need a clk gating on pc_addr + instruction_counter #(width) PC (clk, rst, pc_we, pc_addr_write, pc_addr); + gatereg #(width, 2) gate_pc_addr(clk, rst, 1, pc_addr, pc_addr_2); + + + logic [2**width-1:0] rom_rd; + logic [2**width-1:0] rom_addr; + logic [2**width-1:0] instruction, instruction_1; + rom #(romsz, width) ROM (rom_addr, rom_rd); + gatereg #(width, 1) gate_pc_addr(clk, rst, 1, pc_addr, rom_addr); + gatereg #(width, 1) gate_instruction(clk, rst, 1, rom_rd, instruction); + gatereg #(width, 1) gate_instruction_1(clk, rst, 1, instruction, instruction_1); + + + logic [0:0] cu_m2r, cu_m2w, cu_b, cu_alu_src, cu_rdst, cu_rw; + logic [3:0] cu_alu_fn, ALU_FN; + logic [0:0] B, MEM_WE, RDST, ALU_SRC, REG_WE, REGW_MEM_OR_RD; + control_unit CONTROL_UNIT (instruction[31:26], instruction[5:0], + cu_m2r, cu_m2w, cu_b, cu_alu_fn, cu_alu_src, cu_rdst, cu_rw + ); + gatereg #(0, 1) gate_cu_rdst (clk, rst, 1, cu_rdst, RDST); + gatereg #(0, 1) gate_cu_alu_src (clk, rst, 1, cu_alu_src, ALU_SRC); + gatereg #(2, 1) gate_cu_alu_fn (clk, rst, 1, cu_alu_fn, ALU_FN); + + gatereg #(0, 2) gate_cu_b (clk, rst, 1, cu_b, B); + gatereg #(0, 2) gate_cu_m2w (clk, rst, 1, cu_m2w, MEM_WE); + + gatereg #(0, 3) gate_cu_rw (clk, rst, 1, cu_rw, REG_WE); + gatereg #(0, 3) gate_cu_m2r (clk, rst, 1, cu_m2r, REGW_MEM_OR_RD); + + logic [2**width-1:0] regf_rs, regf_rs_1; + logic [2**width-1:0] regf_rt, regf_rt_1, regf_rt_2; + logic [7:0] regf_a3, regf_a3_2; + assign rd = (REGW_MEM_OR_RD) ? rd_mem : alu_out_2; + assign regf_a3 = (RDST) ? instruction_1[15:11] : instruction_1[20:16]; + // TODO: Connect inputs + gatereg #(3, 2) gate_regf_a3 (clk, rst, 1, regf_a3, regf_a3_2); + register_file #(width, 5) REGS ( + ~clk, REG_WE, + regf_a3_2 & 8'b00011111, rd, + instruction[25:21], regf_rs, + instruction[20:16], regf_rt, + regs_out + ); + gatereg #(width, 1) gate_regf_rs(clk, rst, 1, regf_rs, regf_rs_1); + gatereg #(width, 1) gate_regf_rt(clk, rst, 1, regf_rt, regf_rt_1); + gatereg #(width, 1) gate_regf_rt_1(clk, rst, 1, regf_rt_1, regf_rt_2); + + logic [2**width-1:0] sign_ext_imm, rt_imm; + sign_extender #(4, width) SIGNEXT(1'b1, instruction[15:0], sign_ext_imm); + gatereg #(width, 1) gate_sign_ext_imm(clk, rst, 1, sign_ext_imm, rt_imm); + + + logic [2**width-1:0] alu_out, alu_out_1, alu_out_2; + logic [3:0] alu_flags, alu_flags_1; + alu #(width) ALU (ALU_FN, regf_rs_1, (ALU_SRC) ? rt_imm : regf_rt_1, rd_alu, alu_flags); + gatereg #(width, 1) gate_alu_out (clk, rst, 1, alu_out, alu_out_1); + gatereg #(width, 1) gate_alu_out_1 (clk, rst, 1, alu_out_1, alu_out_2); + gatereg #(width, 1) gate_alu_flags (clk, rst, 1, alu_flags, alu_flags_1); + + logic [2**width-1:0] new_pc_addr, new_pc_addr_1; + assign new_pc_addr = (rt_imm << 2) + pc_addr_2; + gatereg #(width, 1) gate_new_pc_addr (clk, rst, 1, new_pc_addr, new_pc_addr_1); + + + assign pc_addr_write = new_pc_addr_1; + assign pc_we = B & alu_flags_1[2]; + logic [2**width-1:0] mem_out, mem_out_1; + ram #(ramsz, width) RAM (clk, rst, alu_out_1, MEM_WE, regf_rt_2, mem_out); + gatereg #(width, 1) gate_mem_out (clk, rst, 1, mem_out, mem_out_1); + assign rd_mem = mem_out_1; +endmodule +`endif \ No newline at end of file