From 50d436d7d13d65f13307926303c3bf713b04280a Mon Sep 17 00:00:00 2001 From: DanielTaoHuang123 Date: Mon, 9 Jun 2025 20:27:20 -0400 Subject: [PATCH 1/2] update ControlFSM testbench update ControlFSM_tb.sv fix a little problem in params.vh to run the test, put ControlFSM.v ControlFSM_tb.sv and params.vh together --- src/params.vh | 2 +- test/ControlFSM_tb.sv | 130 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 test/ControlFSM_tb.sv diff --git a/src/params.vh b/src/params.vh index d9c2cdd..767bc58 100644 --- a/src/params.vh +++ b/src/params.vh @@ -14,7 +14,7 @@ parameter ALUAdd = 4'b0000; parameter ALUSub = 4'b0001; parameter ALUSLL = 4'b0010; parameter ALUSLT = 4'b0011; -parameter ALUSLTU = = 4'b0100; +parameter ALUSLTU = 4'b0100; parameter ALUXOR = 4'b0101; parameter ALUSRL = 4'b0110; parameter ALUSRA = 4'b0111; diff --git a/test/ControlFSM_tb.sv b/test/ControlFSM_tb.sv new file mode 100644 index 0000000..c031c68 --- /dev/null +++ b/test/ControlFSM_tb.sv @@ -0,0 +1,130 @@ +//to test ControlFSM, put this file, ControlFSM.v and params.vh in the same folder, and add this following line to the ControlFSM.v before running the test +//`include "params.vh" +`timescale 1ns / 1ps + +module ControlFSM_tb; + + // Inputs + logic CLOCK_50; + logic reset; + logic [6:0] opcode; + + // Outputs + logic AdrSrc; + logic IRWrite; + logic RegWrite; + logic PCUpdate; + logic MemWrite; + logic Branch; + logic [1:0] ALUSrcA; + logic [1:0] ALUSrcB; + logic [2:0] ALUOp; + logic [1:0] ResultSrc; + logic [3:0] FSMState; + + + ControlFSM control_fsm ( + .opcode(opcode), + .clk(CLOCK_50),//using CLOCK_50 as the clk + .reset(reset), + .AdrSrc(AdrSrc), + .IRWrite(IRWrite), + .RegWrite(RegWrite), + .PCUpdate(PCUpdate), + .MemWrite(MemWrite), + .Branch(Branch), + .ALUSrcA(ALUSrcA), + .ALUSrcB(ALUSrcB), + .ALUOp(ALUOp), + .ResultSrc(ResultSrc), + .FSMState(FSMState) + ); + + parameter CLOCK_PERIOD = 10; + initial begin + CLOCK_50 <= 1'b0; + end // initial + always @ (*) + begin : Clock_Generator + #((CLOCK_PERIOD) / 2) CLOCK_50 <= ~CLOCK_50; + end + + task apply_opcode(input [6:0] opc); + begin + opcode = opc; + #10; // Wait for state transition +$display("Time: %0t | State: %0d | Opcode: %b\n\ +AdrSrc: %b | IRWrite: %b | RegWrite: %b | PCUpdate: %b | MemWrite: %b | Branch: %b\n\ +ALUSrcA: %b | ALUSrcB: %b | ALUOp: %b | ResultSrc: %b", + $time, FSMState, opcode, + AdrSrc, IRWrite, RegWrite, PCUpdate, MemWrite, Branch, + ALUSrcA, ALUSrcB, ALUOp, ResultSrc); + end + endtask + + task print; + begin + $display("Time: %0t | State: %0d | Opcode: %b\n\ +AdrSrc: %b | IRWrite: %b | RegWrite: %b | PCUpdate: %b | MemWrite: %b | Branch: %b\n\ +ALUSrcA: %b | ALUSrcB: %b | ALUOp: %b | ResultSrc: %b", + $time, FSMState, opcode, + AdrSrc, IRWrite, RegWrite, PCUpdate, MemWrite, Branch, + ALUSrcA, ALUSrcB, ALUOp, ResultSrc); + end + endtask + + integer i; + + initial begin + // Initialize inputs + reset = 1; + opcode = 7'b0000000; + + // Apply reset + #10; + reset = 0; + + // Apply different opcodes and observe transitions + apply_opcode(7'b0110011); // R-type + for (i = 0; i < 3; i = i + 1) begin + #10; + print(); + end + + apply_opcode(7'b0010011); // I-type + for (i = 0; i < 3; i = i + 1) begin + #10; + print(); + end + + apply_opcode(7'b0000011); // Load + for (i = 0; i < 4; i = i + 1) begin + #10; + print(); + end + + apply_opcode(7'b0100011); // Store + for (i = 0; i < 4; i = i + 1) begin + #10; + print(); + end + + apply_opcode(7'b1101111); // JAL + for (i = 0; i < 3; i = i + 1) begin + #10; + print(); + end + + apply_opcode(7'b1100011); // BEQ + for (i = 0; i < 3; i = i + 1) begin + #10; + print(); + end + + // Done + #20; + $finish; + + end + +endmodule \ No newline at end of file From b2e88b602303f6cd825e76df51587c7740dac090 Mon Sep 17 00:00:00 2001 From: DanielTaoHuang123 Date: Wed, 25 Jun 2025 17:40:14 -0400 Subject: [PATCH 2/2] add hazard_unit.v --- src/hazard_unit.v | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/hazard_unit.v diff --git a/src/hazard_unit.v b/src/hazard_unit.v new file mode 100644 index 0000000..22dbb33 --- /dev/null +++ b/src/hazard_unit.v @@ -0,0 +1,43 @@ +module hazard_unit ( + input wire clk, + input wire Rs1E, + input wire RdM, + input wire RdW, + input wire RegWriteM, + input wire [1:0] ResultSrcE, + input wire Rs1D, + input wire Rs2D, + input wire RdE, + input wire PCSrcE, + output reg [1:0] ForwardAE, + output reg lwStall, + output reg StallF, + output reg StallD, + output reg FlushD, + output reg FlushE + ) + + wire ResultSrcE0; + assign ResultSrcE0 = ResultSrcE[0]; + +//Forward + always @ (posedge clk) begin + if (((Rs1E == RdM)&RegWriteM)&(Rs1E!=0)) ForwardAE <= 2'b10; + else if (((Rs1E == RdW)&RegWriteM)&(Rs1E!=0)) ForwardAE <= 2'b01; + else ForwardAE <= 2'b00; + end + +//Stall when a load hazard occurs + always @ (posedge clk) begin + lwStall <= ResultSrcE0 & ((Rs1D == RdE)|(Rs2D == RdE)); + StallF <= lwStall; + StallD <= lwStall; + end + +//Flush when a control hazard occurs + always @ (posedge clk) begin + FlushD <= PCSrcE; + FlushE <= lwStall | PCSrcE; + end + +endmodule \ No newline at end of file