Files
FPGA_Uni/modules/assignment3.sv
T

98 lines
3.7 KiB
Systemverilog

`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"
module assignment3 #(width=5, romsz=9, ramsz=10)(
input logic [0:0] clk, input logic [0:0] rst
);
logic [31:0] regs_out [32];
logic [2**width-1:0] pc_addr, pc_addr_1, 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, 1) gate_pc_addr(clk, rst, 1'b1, pc_addr, pc_addr_1);
gatereg #(width, 1) gate_pc_addr_1(clk, rst, 1'b1, pc_addr_1, pc_addr_2);
logic [2**width-1:0] rom_rd;
logic [2**width-1:0] instruction, instruction_1;
rom #("./asm/bin/ELEC4720-2026s2-Ass-03-NoHazardsDemo.hex", romsz, width) ROM (pc_addr_1[romsz-1:0], rom_rd);
gatereg #(width, 1) gate_instruction(clk, rst, 1'b1, rom_rd, instruction);
gatereg #(width, 1) gate_instruction_1(clk, rst, 1'b1, 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'b1, cu_rdst, RDST);
gatereg #(0, 1) gate_cu_alu_src (clk, rst, 1'b1, cu_alu_src, ALU_SRC);
gatereg #(2, 1) gate_cu_alu_fn (clk, rst, 1'b1, cu_alu_fn, ALU_FN);
gatereg #(0, 2) gate_cu_b (clk, rst, 1'b1, cu_b, B);
gatereg #(0, 2) gate_cu_m2w (clk, rst, 1'b1, cu_m2w, MEM_WE);
gatereg #(0, 3) gate_cu_rw (clk, rst, 1'b1, cu_rw, REG_WE);
gatereg #(0, 3) gate_cu_m2r (clk, rst, 1'b1, 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;
logic [2**width-1:0] rd, rd_mem, rd_alu;
assign rd = (REGW_MEM_OR_RD) ? rd_mem : rd_alu;
assign regf_a3 = (RDST) ? instruction_1[15:11] : instruction_1[20:16];
// TODO: Connect inputs
gatereg #(3, 2) gate_regf_a3 (clk, rst, 1'b1, regf_a3, regf_a3_2);
register_file #(width, 5) REGS (
~clk, REG_WE,
regf_a3_2[4:0], rd,
instruction[25:21], regf_rs,
instruction[20:16], regf_rt,
regs_out
);
gatereg #(width, 1) gate_regf_rs(clk, rst, 1'b1, regf_rs, regf_rs_1);
gatereg #(width, 1) gate_regf_rt(clk, rst, 1'b1, regf_rt, regf_rt_1);
gatereg #(width, 1) gate_regf_rt_1(clk, rst, 1'b1, 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'b1, 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, alu_out, alu_flags[2:0]);
gatereg #(width, 1) gate_alu_out (clk, rst, 1'b1, alu_out, alu_out_1);
gatereg #(width, 1) gate_alu_out_1 (clk, rst, 1'b1, alu_out_1, alu_out_2);
gatereg #(2, 1) gate_alu_flags (clk, rst, 1'b1, alu_flags, alu_flags_1);
assign rd_alu = alu_out_2;
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'b1, 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[ramsz-1:0], MEM_WE, regf_rt_2, mem_out);
gatereg #(width, 1) gate_mem_out (clk, rst, 1'b1, mem_out, mem_out_1);
assign rd_mem = mem_out_1;
endmodule
`endif