From 8ea1ad97da582117d66491ee9a3ba76b7f778359 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sat, 25 Sep 2021 13:01:23 -0700 Subject: [PATCH] Fix AMBA AHB 3 Lite widget so that first register transactions succeed --- .gitignore | 8 +- requirements.txt | 3 + .../widgets/srdl2sv_amba3ahblite.sv | 123 +++++++++--------- .../widgets/srdl2sv_amba3ahblite.yaml | 11 +- tests/.gitignore | 2 +- 5 files changed, 75 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index 0e9cc79..39cc3dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ -# Grabbed from https://github.com/github/gitignore/blob/master/Python.gitignore on 05/02/2021 +# SRDL2SV specific +srdl2sv_out + +############################################################################################### +# Grabbed from https://github.com/github/gitignore/blob/master/Python.gitignore on 05/02/2021 # +############################################################################################### # Byte-compiled / optimized / DLL files __pycache__/ @@ -138,4 +143,3 @@ dmypy.json # Cython debug symbols cython_debug/ - diff --git a/requirements.txt b/requirements.txt index d7ae1b3..06f70b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,4 @@ systemrdl-compiler==1.19.0 +cocotb +cocotb-bus +PyYAML diff --git a/srdl2sv/components/widgets/srdl2sv_amba3ahblite.sv b/srdl2sv/components/widgets/srdl2sv_amba3ahblite.sv index 143e2c5..33c78f9 100644 --- a/srdl2sv/components/widgets/srdl2sv_amba3ahblite.sv +++ b/srdl2sv/components/widgets/srdl2sv_amba3ahblite.sv @@ -26,34 +26,35 @@ module srdl2sv_amba3ahblite import srdl2sv_if_pkg::*; #( - parameter bit FLOP_REGISTER_IF = 0 + parameter bit FLOP_REGISTER_IF = 0, + parameter BUS_BITS = 32 ) ( // Outputs to internal logic - output b2r_t b2r, + output b2r_t b2r, // Inputs from internal logic - input r2b_t r2b, + input r2b_t r2b, // Bus protocol - input HCLK, - input HRESETn, - input HSEL, - input [31:0] HADDR, - input HWRITE, - input [ 2:0] HSIZE, - input [ 2:0] HBURST, - input [ 3:0] HPROT, - input [ 1:0] HTRANS, - input [31:0] HWDATA, - input HREADY, - input HMASTLOCK, + input HCLK, + input HRESETn, + input HSEL, + input [31:0] HADDR, + input HWRITE, + input [ 2:0] HSIZE, + input [ 3:0] HPROT, // Might be used in the future together with an RDL UDP + input [ 1:0] HTRANS, + input [BUS_BITS-1:0] HWDATA, - output logic HREADYOUT, - output logic HRESP, - output logic [31:0] HRDATA + output logic HREADYOUT, + output logic HRESP, + output logic [BUS_BITS-1:0] HRDATA ); + localparam BUS_BYTES = BUS_BITS/8; + localparam BUS_BYTES_W = $clog2(BUS_BYTES); + /*********************** * Define enums ***********************/ @@ -85,13 +86,11 @@ module srdl2sv_amba3ahblite WRITE = 1'b1 } OP_t; - typedef enum logic [2:0] { - FSM_IDLE = 3'b000, - FSM_NONSEQ= 3'b001, - FSM_SEQ = 3'b010, - FSM_WAIT = 3'b011, - FSM_ERR_0 = 3'b100, - FSM_ERR_1 = 3'b101 + typedef enum logic [1:0] { + FSM_IDLE = 2'b00, + FSM_TRANS = 2'b01, + FSM_ERR_0 = 2'b10, + FSM_ERR_1 = 2'b11 } fsm_t; /**************************** @@ -100,7 +99,7 @@ module srdl2sv_amba3ahblite logic [31:0] addr_q; OP_t operation_q; - wire addr_err = (HADDR[2:0] % HSIZE) != 3'b0; + wire addr_err = HADDR % (32'b1 << HSIZE) != 32'b0; always_ff @ (posedge HCLK) begin @@ -113,16 +112,16 @@ module srdl2sv_amba3ahblite // of extending the address phase of the next transfer if (HREADYOUT) begin - addr_q <= HADDR; + // Floor address. Sub-register access will be handled by byte-enables + addr_q <= {HADDR[BUS_BITS-1:BUS_BYTES_W], {BUS_BYTES_W{1'b0}}}; operation_q <= HWRITE ? WRITE : READ; end end SEQ: begin if (HREADYOUT) - begin - addr_q <= addr_q; // TODO - end + // Floor address. Sub-register access will be handled by byte-enables + addr_q <= {HADDR[BUS_BITS-1:BUS_BYTES_W], {BUS_BYTES_W{1'b0}}}; end endcase end @@ -153,16 +152,15 @@ module srdl2sv_amba3ahblite fsm_next = FSM_ERR_0; else if (HTRANS == NONSEQ) // If NONSEQ, go to NONSEQ state - fsm_next = FSM_NONSEQ; + fsm_next = FSM_TRANS; else if (HTRANS == SEQ) // If a SEQ is provided, something is wrong fsm_next = FSM_ERR_0; end end - FSM_NONSEQ: + FSM_TRANS: begin HREADYOUT = r2b.rdy; - b2r_w_vld_next = operation_q == WRITE; b2r_r_vld_next = operation_q == READ; @@ -173,30 +171,24 @@ module srdl2sv_amba3ahblite else if (HTRANS == BUSY) begin // Wait - fsm_next = FSM_NONSEQ; + fsm_next = FSM_TRANS; end else if (HTRANS == NONSEQ) begin // Another unrelated access is coming - fsm_next = FSM_NONSEQ; + fsm_next = FSM_TRANS; end else if (HTRANS == SEQ) begin - // Entering a burst - fsm_next = r2b.rdy ? FSM_SEQ : FSM_NONSEQ; + // Another part of the burst is coming + fsm_next = FSM_TRANS; end else if (HTRANS == IDLE) begin // All done, wrapping things up! - fsm_next = r2b.rdy ? FSM_IDLE : FSM_NONSEQ; + fsm_next = r2b.rdy ? FSM_IDLE : FSM_TRANS; end end - FSM_SEQ: - begin - end - FSM_WAIT: - begin - end FSM_ERR_0: begin HREADYOUT = 0; @@ -205,21 +197,32 @@ module srdl2sv_amba3ahblite begin // Slaves must always provide a zero wait state OKAY response // to BUSY transfers and the transfer must be ignored by the slave. - HRESP = 0; + HRESP = OKAY; fsm_next = FSM_ERR_0; end else begin - HRESP = 1; + HRESP = ERROR; fsm_next = FSM_ERR_1; end end FSM_ERR_1: begin - HREADYOUT = 1; - HRESP = 1; + if (HTRANS == BUSY) + begin + // Slaves must always provide a zero wait state OKAY response + // to BUSY transfers and the transfer must be ignored by the slave. + HREADYOUT = 0; + HRESP = OKAY; + fsm_next = FSM_ERR_0; + end + else + begin + HREADYOUT = 1; + HRESP = ERROR; - fsm_next = FSM_IDLE; + fsm_next = FSM_IDLE; + end end endcase end @@ -234,19 +237,19 @@ module srdl2sv_amba3ahblite /*** * Determine the number of active bytes ***/ + logic [3:0] HSIZE_bitfielded; logic [3:0] b2r_byte_en_next; logic b2r_w_vld_next; logic b2r_r_vld_next; - //always_comb - //begin - // case (HTRANS) - // 3'b000 : b2r_byte_en_next = 4'b0001; - // 3'b001 : b2r_byte_en_next = 4'b0011; - // 3'b010 : b2r_byte_en_next = 4'b1111; - // default: b2r_byte_en_next = 4'b1111; - // endcase - //end + always_comb + begin + for (int i = 0; i < BUS_BYTES; i++) + HSIZE_bitfielded[i] = i < (1 << HSIZE); + + // Shift if not the full bus is accessed + b2r_byte_en_next = HSIZE_bitfielded << (HADDR % BUS_BYTES); + end /*** * Drive interface to registers @@ -269,7 +272,7 @@ module srdl2sv_amba3ahblite always_ff @ (posedge HCLK) begin b2r.addr <= addr_q; - b2r.data <= HWDATA; + b2r.data <= HWDATA << HADDR[BUS_BYTES_W-1:0]; b2r.byte_en <= b2r_byte_en_next; end end @@ -278,7 +281,7 @@ module srdl2sv_amba3ahblite assign b2r.w_vld = b2r_w_vld_next; assign b2r.r_vld = b2r_r_vld_next; assign b2r.addr = addr_q; - assign b2r.data = HWDATA; + assign b2r.data = HWDATA << HADDR[BUS_BYTES_W-1:0]; assign b2r.byte_en = b2r_byte_en_next; end endgenerate diff --git a/srdl2sv/components/widgets/srdl2sv_amba3ahblite.yaml b/srdl2sv/components/widgets/srdl2sv_amba3ahblite.yaml index 2c9a161..6a890f8 100644 --- a/srdl2sv/components/widgets/srdl2sv_amba3ahblite.yaml +++ b/srdl2sv/components/widgets/srdl2sv_amba3ahblite.yaml @@ -12,6 +12,8 @@ module_instantiation: * - clk -> Clock that drives registers and the bus *******************************************************************/ srdl2sv_amba3ahblite + #(.FLOP_REGISTER_IF (0), + .BUS_BITS (32)) srdl2sv_amba3ahblite_inst (// Outputs to internal logic .b2r, @@ -25,13 +27,10 @@ module_instantiation: .HADDR, .HWRITE, .HSIZE, - .HBURST, .HPROT, .HTRANS, .HWDATA, - .HREADY, .HSEL, - .HMASTLOCK, .HREADYOUT, .HRESP, @@ -52,20 +51,14 @@ module_instantiation: signal_type: '' - name: 'HSIZE' signal_type: '[2:0]' - - name: 'HBURST' - signal_type: '[2:0]' - name: 'HPROT' signal_type: '[3:0]' - name: 'HTRANS' signal_type: '[1:0]' - name: 'HWDATA' signal_type: '[31:0]' - - name: 'HREADY' - signal_type: '' - name: 'HSEL' signal_type: '' - - name: 'HMASTLOCK' - signal_type: '' output_ports: - name: 'HREADYOUT' signal_type: '' diff --git a/tests/.gitignore b/tests/.gitignore index 9a46904..eef769d 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,2 +1,2 @@ -srdl2sv_out *.fst +sim_build