X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=cpu_fetch_stage.py;h=3eae2adfa03a1e4589eb6f527d68eb6f4363958e;hb=c714d2845b185d8ce5d54fae0f29e7bf825539c7;hp=a120573b6499ed1ca98ba2e2e298fbb22fffa4c9;hpb=2d4a23664382c3192bb492218ce01c07353ca118;p=rv32.git diff --git a/cpu_fetch_stage.py b/cpu_fetch_stage.py index a120573..3eae2ad 100644 --- a/cpu_fetch_stage.py +++ b/cpu_fetch_stage.py @@ -26,85 +26,102 @@ from migen import * from migen.fhdl import verilog -from riscvdefs import * +#from riscvdefs import * from cpudefs import * -reset_vector = 32'hXXXXXXXX; -mtvec = 32'hXXXXXXXX; class CPUFetchStage(Module): def __init__(self): self.clk = ClockSignal() self.reset = ResetSignal() + self.reset_vector = Signal(32) #32'hXXXXXXXX; - parameter + self.mtvec = Signal(32) # 32'hXXXXXXXX; - parameter #output [31:2] memory_interface_fetch_address, - self.memory_interface_fetch_address = Signal(32)[2:] + self.memory_interface_fetch_address = Signal(32) #input [31:0] memory_interface_fetch_data, self.memory_interface_fetch_data = Signal(32) self.memory_interface_fetch_valid = Signal() - input `fetch_action fetch_action, - input [31:0] target_pc, - self.output_pc = Signal(32, reset=reset_vector) + self.fetch_action = Signal(fetch_action) + self.target_pc = Signal(32) + self.output_pc = Signal(32, reset=self.reset_vector) self.output_instruction = Signal(32) - output reg `fetch_output_state output_state - - self.comb += [ - self.cd_sys.clk.eq(self.clk), - self.cd_sys.rst.eq(self.reset) - ] + self.output_state = Signal(fetch_output_state, + reset=fetch_output_state_empty) - fetch_pc = Signal(32, reset=reset_vector) - - self.sync += output_pc.eq((fetch_action == `fetch_action_wait) ? output_pc : fetch_pc); - - memory_interface_fetch_address = fetch_pc[31:2]; + #self.comb += [ + # self.cd_sys.clk.eq(self.clk), + # self.cd_sys.rst.eq(self.reset) + #] - initial output_pc <= reset_vector; - initial output_state <= `fetch_output_state_empty; - - delayed_instruction = Signal(32, reset=0); - delayed_instruction_valid = Signal(reset=0); - - self.sync += delayed_instruction.eq(output_instruction) - - assign output_instruction = delayed_instruction_valid ? delayed_instruction : memory_interface_fetch_data; - - self.sync += delayed_instruction_valid.eq(fetch_action == `fetch_action_wait) - - always @(posedge clk or posedge reset) begin - if(reset) begin - output_state <= `fetch_output_state_empty; - end - else begin - case(fetch_action) - `fetch_action_default, - `fetch_action_ack_trap: begin - if(memory_interface_fetch_valid) begin - fetch_pc <= fetch_pc + 4; - output_state <= `fetch_output_state_valid; - end - else begin - fetch_pc <= mtvec; - output_state <= `fetch_output_state_trap; - end - end - `fetch_action_fence: begin - fetch_pc <= output_pc + 4; - output_state <= `fetch_output_state_empty; - end - `fetch_action_jump: begin - fetch_pc <= target_pc; - output_state <= `fetch_output_state_empty; - end - `fetch_action_error_trap, - `fetch_action_noerror_trap: begin - fetch_pc <= mtvec; - output_state <= `fetch_output_state_empty; - end - `fetch_action_wait: begin - fetch_pc <= fetch_pc; - output_state <= `fetch_output_state_valid; - end - endcase - end - end - endmodule + fetch_pc = Signal(32, reset=self.reset_vector) + + self.sync += If(self.fetch_action != FA.wait, + self.output_pc.eq(fetch_pc)) + + self.comb += self.memory_interface_fetch_address.eq(fetch_pc[2:]) + + #initial output_pc <= self.reset_vector; + #initial output_state <= `fetch_output_state_empty; + + delayed_instruction = Signal(32, reset=0) + delayed_instruction_valid = Signal(reset=0) + + self.sync += delayed_instruction.eq(self.output_instruction) + + self.comb += If(delayed_instruction_valid, + self.output_instruction.eq(delayed_instruction) + ).Else( + self.output_instruction.eq(self.memory_interface_fetch_data) + ) + + self.sync += delayed_instruction_valid.eq(self.fetch_action == + FA.wait) + + fc = { + FA.ack_trap: + If(self.memory_interface_fetch_valid, + [fetch_pc.eq(fetch_pc + 4), + self.output_state.eq(fetch_output_state_valid)] + ).Else( + [fetch_pc.eq(self.mtvec), + self.output_state.eq(fetch_output_state_trap)] + ), + FA.fence: + [ fetch_pc.eq(self.output_pc + 4), + self.output_state.eq(fetch_output_state_empty) + ], + FA.jump: + [ fetch_pc.eq(self.target_pc), + self.output_state.eq(fetch_output_state_empty) + ], + FA.error_trap: + [fetch_pc.eq(self.mtvec), + self.output_state.eq(fetch_output_state_empty) + ], + FA.wait: + [fetch_pc.eq(fetch_pc), + self.output_state.eq(fetch_output_state_valid) + ] + } + fc[FA.default] = fc[FA.ack_trap] + fc[FA.noerror_trap] = fc[FA.error_trap] + self.sync += Case(self.fetch_action, + fc).makedefault(FA.default) + +if __name__ == "__main__": + example = CPUFetchStage() + #memory_interface_fetch_address = Signal(32) + print(verilog.convert(example, + { #example.clk, + #example.reset, + example.memory_interface_fetch_address, + example.memory_interface_fetch_data, + example.memory_interface_fetch_valid, + example.fetch_action, + example.target_pc, + example.output_pc, + example.output_instruction, + example.output_state, + example.reset_vector, + example.mtvec + }))