diff --git a/hardware/simulation/src/iob_soc_tb.cpp b/hardware/simulation/src/iob_soc_tb.cpp index a1627da16..8aaf6edf6 100644 --- a/hardware/simulation/src/iob_soc_tb.cpp +++ b/hardware/simulation/src/iob_soc_tb.cpp @@ -67,13 +67,13 @@ void uartread(unsigned int cpu_address, char *read_reg) { Timer(CLK_PERIOD); } Timer(CLK_PERIOD); + dut->uart_valid_i = 0; if (!dut->uart_rvalid_o) { Timer(CLK_PERIOD); } Timer(CLK_PERIOD); *read_reg = (dut->uart_rdata_o) >> ((cpu_address & 0b011) * 8); // align to 32 bits - dut->uart_valid_i = 0; } void inituart() { diff --git a/submodules/LIB/hardware/modules/apb2iob/hardware/src/apb2iob.v b/submodules/LIB/hardware/modules/apb2iob/hardware/src/apb2iob.v index de81ba5e9..5f161fd9c 100644 --- a/submodules/LIB/hardware/modules/apb2iob/hardware/src/apb2iob.v +++ b/submodules/LIB/hardware/modules/apb2iob/hardware/src/apb2iob.v @@ -21,68 +21,71 @@ module apb2iob #( ); localparam WSTRB_W = DATA_W / 8; + localparam WAIT_ENABLE = 2'd0; + localparam WAIT_READY = 2'd1; + localparam WAIT_RVALID = 2'd2; + localparam WAIT_APB_READY = 2'd3; + reg iob_valid; reg apb_ready_nxt; assign iob_valid_o = iob_valid; - assign iob_addr_o = apb_addr_i; - assign iob_wdata_o = apb_wdata_i; - assign iob_wstrb_o = apb_write_i ? apb_wstrb_i : {WSTRB_W{1'b0}}; + assign iob_addr_o = apb_addr_i; + assign iob_wdata_o = apb_wdata_i; + assign iob_wstrb_o = apb_write_i ? apb_wstrb_i : {WSTRB_W{1'b0}}; //program counter - wire [1:0] pc; - reg [1:0] pc_nxt; + wire [1:0] pc_cnt; + reg [1:0] pc_cnt_nxt; iob_reg #( .DATA_W (2), .RST_VAL(2'd0) - ) access_reg ( + ) pc_reg ( `include "clk_en_rst_s_s_portmap.vs" - .data_i(pc_nxt), - .data_o(pc) + .data_i(pc_cnt_nxt), + .data_o(pc_cnt) ); - assign apb_ready_nxt = apb_write_i? iob_ready_i : iob_rvalid_i; - always @* begin - pc_nxt = pc + 1'b1; - iob_valid = 1'b0; + pc_cnt_nxt = pc_cnt + 1'b1; + iob_valid = 1'b0; apb_ready_nxt = 1'b0; - - case (pc) - 0: begin - if(!(apb_sel_i & apb_enable_i)) begin - iob_valid = 1'b1; - pc_nxt = pc; - end - end - 1: begin - iob_valid = 1'b1; - if(!iob_ready_i) begin - pc_nxt = pc; - end else begin - if(apb_write_i) begin - pc_nxt = 2'd0; - apb_ready_nxt = 1'b1; - end - end - end - 2: begin - iob_valid = 1'b1; - if (!iob_rvalid_i) begin - pc_nxt = pc; - end else begin - apb_ready_nxt = 1'b1; - end - end - default: begin - pc_nxt = 2'd0; - end + + case (pc_cnt) + WAIT_ENABLE: begin + if (!(apb_sel_i & apb_enable_i)) begin + pc_cnt_nxt = pc_cnt; + end else begin + iob_valid = 1'b1; + end + end + WAIT_READY: begin + iob_valid = 1'b1; + if (!iob_ready_i) begin + pc_cnt_nxt = pc_cnt; + end else begin + if (apb_write_i) begin + pc_cnt_nxt = WAIT_APB_READY; + apb_ready_nxt = 1'b1; + end + end + end + WAIT_RVALID: begin + if (!iob_rvalid_i) begin + pc_cnt_nxt = pc_cnt; + end else begin + apb_ready_nxt = 1'b1; + end + end + default: begin // WAIT_APB_READY + pc_cnt_nxt = WAIT_ENABLE; + end endcase - end // always @ * - + end // always @ * + - //APB outputs + //APB outputs iob_reg #( .DATA_W (1), .RST_VAL(1'd0) @@ -97,7 +100,7 @@ module apb2iob #( .RST_VAL({DATA_W{1'd0}}) ) apb_rdata_reg ( `include "clk_en_rst_s_s_portmap.vs" - .en_i(iob_rvalid_i), + .en_i (iob_rvalid_i), .data_i(iob_rdata_i), .data_o(apb_rdata_o) ); diff --git a/submodules/LIB/hardware/modules/iob2apb/hardware/src/iob2apb.v b/submodules/LIB/hardware/modules/iob2apb/hardware/src/iob2apb.v index 2ccae5fd6..9415c00eb 100644 --- a/submodules/LIB/hardware/modules/iob2apb/hardware/src/iob2apb.v +++ b/submodules/LIB/hardware/modules/iob2apb/hardware/src/iob2apb.v @@ -20,62 +20,61 @@ module iob2apb #( // APB master interface `include "apb_m_port.vs" ); - + + localparam WAIT_VALID = 2'd0; + localparam WAIT_READY = 2'd1; + //IOb outputs assign iob_ready_o = apb_ready_i; - //APB outputs reg apb_enable; - assign apb_sel_o = apb_enable; + assign apb_sel_o = apb_enable; assign apb_enable_o = apb_enable; - - assign apb_addr_o = iob_addr_i; - assign apb_wstrb_o = iob_wstrb_i; - assign apb_write_o = |iob_wstrb_i; - + assign apb_wdata_o = iob_wdata_i; + + assign apb_addr_o = iob_addr_i; + assign apb_wstrb_o = iob_wstrb_i; + assign apb_write_o = |iob_wstrb_i; //program counter - wire [1:0] pc; - reg [1:0] pc_nxt; + wire [1:0] pc; + reg [1:0] pc_nxt; iob_reg #( .DATA_W (2), .RST_VAL(0) - ) access_reg ( + ) pc_reg ( `include "clk_en_rst_s_s_portmap.vs" .data_i(pc_nxt), .data_o(pc) ); - - always @* begin - - pc_nxt = pc + 1'b1; - + pc_nxt = pc + 1'b1; apb_enable = 1'b0; - + case (pc) - 0: begin - if (!iob_valid_i) begin - pc_nxt = pc; - end else begin - apb_enable = 1'b1; - end - end - 1: begin - apb_enable = 1'b1; - if (!apb_ready_i) begin - pc_nxt = pc; - end else - end - default: begin - pc_nxt = 0; - end + WAIT_VALID: begin + if (!iob_valid_i) begin + pc_nxt = pc; + end else begin + apb_enable = 1'b1; + end + end + WAIT_READY: begin + apb_enable = 1'b1; + if (!apb_ready_i) begin + pc_nxt = pc; + end else if (apb_write_o) begin // No need to wait for rvalid + pc_nxt = WAIT_VALID; + end + end + default: begin + pc_nxt = WAIT_VALID; + end endcase end - //IOb outputs iob_reg #( .DATA_W (DATA_W), @@ -95,15 +94,4 @@ module iob2apb #( .data_o(iob_rvalid_o) ); - iob_reg #( - .DATA_W (DATA_W), - .RST_VAL(0) - ) iob_wready_reg ( - `include "clk_en_rst_s_s_portmap.vs" - .data_i(apb_rdata_i), - .data_o(iob_rdata_o) - ); - - - endmodule diff --git a/submodules/LIB/scripts/mkregs.py b/submodules/LIB/scripts/mkregs.py index 94f5dcf65..d5680942c 100755 --- a/submodules/LIB/scripts/mkregs.py +++ b/submodules/LIB/scripts/mkregs.py @@ -643,8 +643,6 @@ def write_hwcode(self, table, out_dir, top, csr_if): default: begin // WAIT_RVALID if(rvalid_int) begin rvalid_nxt = 1'b1; - end - if (iob_rvalid_o) begin state_nxt = WAIT_REQ; end end