diff --git a/processor/datapipe/EX.sv b/processor/datapipe/EX.sv index 220224a..301cc8f 100644 --- a/processor/datapipe/EX.sv +++ b/processor/datapipe/EX.sv @@ -26,56 +26,56 @@ module EX( input logic [RegWidth-1:0] iFwMe ); -// logic [RegWidth-1:0] ALU_A, ALU_B, ALU_Z; -// -// logic [6:0] ALU_F7; -// logic [2:0] ALU_F3; -// -// ALU alu( -// .iA(ALU_A), -// .iB(ALU_B), -// .iFunc3(iID.ctrl.func3), -// .iFunc7(iID.ctrl.func7), -// .oZ(ALU_Z) -// ); -// -// always_comb begin -// if(iFwMeS1_en) -// ALU_A = iFwMe; -// else if(iFwExS1_en) -// ALU_A = oMEM.rd.value; -// else -// ALU_A = iID.rs1.value; -// -// if(iFwMeS2_en) -// ALU_B = iFwMe; -// else if(iFwExS2_en) -// ALU_B = oMEM.rd.value; -// else if(iID.ctrl.imm_en) -// ALU_B = iID.immediate; -// else -// ALU_B = iID.rs2.value; -// -// if(iID.ctrl.ex_en && iID.ctrl.valid) begin -// ALU_F7 = iID.ctrl.func7; -// ALU_F3 = iID.ctrl.func3; -// end else begin -// ALU_F7 = 7'd0; -// ALU_F3 = 3'd0; -// end -// -// end -// -// always_ff @(posedge iClk, negedge nRst) begin -// if(!nRst) -// oMEM = '0; -// else if(!iStall) begin -// oMEM.ctrl = iID.ctrl; -// oMEM.rs = iID.rs2; -// oMEM.rd.addr = iID.rd_addr; -// oMEM.rd.value = ALU_Z; -// end -// end +logic [RegWidth-1:0] ALU_A, ALU_B, ALU_Z; + +logic [6:0] ALU_F7; +logic [2:0] ALU_F3; + +ALU alu( + .iA(ALU_A), + .iB(ALU_B), + .iFunc3(iID.ctrl.func3), + .iFunc7(iID.ctrl.func7), + .oZ(ALU_Z) +); + +always_comb begin + if(iFwMeS1_en) + ALU_A = iFwMe; + else if(iFwExS1_en) + ALU_A = oMEM.rd.value; + else + ALU_A = iID.rs1.value; + + if(iFwMeS2_en) + ALU_B = iFwMe; + else if(iFwExS2_en) + ALU_B = oMEM.rd.value; + else if(iID.ctrl.imm_en) + ALU_B = iID.immediate; + else + ALU_B = iID.rs2.value; + + if(iID.ctrl.ex_en && iID.ctrl.valid) begin + ALU_F7 = iID.ctrl.func7; + ALU_F3 = iID.ctrl.func3; + end else begin + ALU_F7 = 7'd0; + ALU_F3 = 3'd0; + end + +end + +always_ff @(posedge iClk, negedge nRst) begin + if(!nRst) + oMEM = '0; + else if(!iStall) begin + oMEM.ctrl = iID.ctrl; + oMEM.rs = iID.rs2; + oMEM.rd.addr = iID.rd_addr; + oMEM.rd.value = ALU_Z; + end +end endmodule diff --git a/processor/sim/SuperStruct.py b/processor/sim/SuperStruct.py index fa5304c..fc91472 100644 --- a/processor/sim/SuperStruct.py +++ b/processor/sim/SuperStruct.py @@ -19,7 +19,10 @@ def __init__(self, parent, width=0, offset=0): # Write only Shadow copy of the CoCoTB simulation value self._recent = BinaryValue(None, width, False) self._width = width - self._offset = offset + if isinstance(self._parent, SuperStruct): + self._offset = offset + else: + self._offset = offset if not isinstance(parent, (ModifiableObject, SuperStruct)): raise TypeError("Parent must be CoCoTB Signal or SuperStruct") @@ -32,10 +35,12 @@ def write(self, value): if isinstance(self._parent, ModifiableObject): self._recent = BinaryValue(value, self._width, False) self._parent.value = self._recent + print("Writing to self") elif isinstance(self._parent, SuperStruct): + print("Writing to parent") self._parent.write(value) else: - pass + raise TypeError("Cannot Write to unknown type") def write_bits(self, low, high, value): """ Write out the whole struct to the simulation @@ -45,18 +50,25 @@ def write_bits(self, low, high, value): high: high position value: Struct Values to write out """ - # Invert width - # if isinstance(self._parent, SuperStruct): - # t_low = low - # low = self._width - high - 1 - # high = self._width - t_low + 1 - t_low = low - low = self._width - high - 1 - high = self._width - t_low - 1 - val = int(self._recent) + # Invert width for parent + if isinstance(self._parent, ModifiableObject): + t_low = low + low = self._width - high - 1 + high = self._width - t_low - 1 + offset = self._offset + # Invert width for child + elif isinstance(self._parent, SuperStruct): + t_low = low + low = self._parent._width - high - 1 + high = self._parent._width - t_low - 1 + offset = -self._offset + else: + raise TypeError("Cannot Arrange bits for value with no parent") + # Get the most recent value + val = int(self._get_recent()) width = high - low + 1 mask = ((1 << width) - 1) << (low + self._offset) - val = (val & ~mask) | ((value & (1 << width) - 1)) << (low + self._offset) + val = (val & ~mask) | ((value & (1 << width) - 1)) << (low + offset) self.write(val) def read(self): @@ -83,3 +95,12 @@ def read_bits(self, low, high): # low = self._width - high - 1 # high = self._width - t_low - 1 return self.read()[low + self._offset:high + self._offset] + + def _get_recent(self) -> BinaryValue: + if isinstance(self._parent, SuperStruct): + return self._parent._get_recent() + elif isinstance(self._parent, ModifiableObject): + return self._recent + else: + raise TypeError("Cannot read from parentNone") + return None diff --git a/processor/sim/pipeline_types.py b/processor/sim/pipeline_types.py index f0d0e41..a1e2b10 100644 --- a/processor/sim/pipeline_types.py +++ b/processor/sim/pipeline_types.py @@ -1,4 +1,5 @@ from SuperStruct import SuperStruct +from cocotb.handle import ModifiableObject from reg_transport_t import reg_transport_t @@ -12,7 +13,7 @@ def opcode(self): @opcode.setter def opcode(self, value): - self.write_bits(0, 6) + self.write_bits(0, 6, value) @property def func3(self): @@ -101,7 +102,7 @@ def instruction(self, value): class id_ex_t(SuperStruct): - def __init__(self, parent): + def __init__(self, parent, input=False): super().__init__(parent, 133) self.ctrl = pipe_control_t(self, 0) self.rs1 = reg_transport_t(self, self.ctrl._width) @@ -128,9 +129,8 @@ def rd_addr(self, value): class ex_mem_t(SuperStruct): - def __init__(self, parent): + def __init__(self, parent, input=False): super().__init__(parent, 133) - # super().__init__(parent, 96) self.ctrl = pipe_control_t(self, 0) self.rs = reg_transport_t(self, self.ctrl._width) rd_base = self.ctrl._width + self.rs._width diff --git a/processor/sim/test_ex.py b/processor/sim/test_ex.py index 9884dbd..27914d5 100644 --- a/processor/sim/test_ex.py +++ b/processor/sim/test_ex.py @@ -37,37 +37,31 @@ def test_ex_runner(): @cocotb.test -async def ex_std_op(dut): +async def ex_sub_tes(dut): await setup_ex(dut) # Setup a sample instruction (sub) await RisingEdge(dut.iClk) iID = id_ex_t(dut.iID) - # iID.ctrl = pipe_control_t(iID) - A = 0x22 - B = 0x11 + A = 100 + B = 55 iID.rs1.value = A - # iID.rs2.value = B - # iID.ctrl.func3 = OpF3AND - # iID.ctrl.func7 = OpF7AND - # iID.ctrl.valid = 1 - # iID.ctrl.wb_en = 1 - # iID.ctrl.ex_en = 1 - # iID.ctrl.imm_en = 0 - # iID.immediate = 0 - print("ID VALUE 1") - print(iID._recent.integer) - # dut.iID.value = iID._recent.integer + iID.rs2.value = B + iID.ctrl.func3 = OpF3SUB + iID.ctrl.opcode = 0x7F + iID.ctrl.func7 = OpF7SUB + iID.ctrl.valid = 1 + iID.ctrl.wb_en = 1 + iID.ctrl.ex_en = 1 + iID.ctrl.imm_en = 0 + iID.immediate = 0x124 + # Value will appear on input on rising edge await RisingEdge(dut.iClk) - ctrl = pipe_control_t(iID) - ctrl.func3 = 0x1 - ctrl.imm_en = 1 - dut.iID.value = ctrl._recent.integer - await RisingEdge(dut.iClk) - print("ID VALUE") - print(iID._recent.integer) - dut.iID.value = iID._recent.integer + # Wait for procesing + # Value latches in output reg on next rising edge await RisingEdge(dut.iClk) # Assert that the instruction was performed correctly oMEM = ex_mem_t(dut.oMEM) - # assert oMEM.rd.value == A-B, "Failed SUB" + assert oMEM.rd.value == A-B, "Failed SUB" + # Add extra sim time for readability + await RisingEdge(dut.iClk) pass