From a7f46682a81d218ca39b32ea210eb4595d0e8b28 Mon Sep 17 00:00:00 2001 From: ST de Feber Date: Fri, 27 Sep 2024 13:37:51 +0200 Subject: [PATCH 1/2] Fixed Avavlon reads The CoCoTb Avalon master driver and corsair do not agree with one and other. The driver removes the addres one a read pulse has been asserted (1 clock cycle) while the hdl of corsair expects it to remain stable for at least one more cycle. This has been fixed by clocking in the address at a read pulse and use that for the read process. --- corsair/templates/amm2lb_verilog.j2 | 7 +++++++ corsair/templates/amm2lb_vhdl.j2 | 9 ++++++++- corsair/templates/regmap_verilog.j2 | 2 +- corsair/templates/regmap_vhdl.j2 | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/corsair/templates/amm2lb_verilog.j2 b/corsair/templates/amm2lb_verilog.j2 index e0dd6e1..c81fbe1 100755 --- a/corsair/templates/amm2lb_verilog.j2 +++ b/corsair/templates/amm2lb_verilog.j2 @@ -78,6 +78,13 @@ wire ren; end end + reg {{ range_decl(config['data_width'] - 1) }} raddr_int; + {{ always_begin(sig='raddr_int', width=config['data_width'], init=read_filler + )}} if (read) begin + raddr_int <= address; + end + end + assign ren = ren_int; {% endmacro %} {{ amm_core() }} diff --git a/corsair/templates/amm2lb_vhdl.j2 b/corsair/templates/amm2lb_vhdl.j2 index 32fc58d..49cf2bd 100644 --- a/corsair/templates/amm2lb_vhdl.j2 +++ b/corsair/templates/amm2lb_vhdl.j2 @@ -95,6 +95,7 @@ signal raddr : std_logic_vector(ADDR_W-1 downto 0); signal ren : std_logic; {% endif %} signal ren_int : std_logic; +signal raddr_int : std_logic_vector(ADDR_W-1 downto 0); {% endmacro %} {{ amm_signals() }} begin @@ -120,8 +121,14 @@ wstrb <= byteenable; end if; {{ process_end() }} +{{ process_begin("raddr_int", "(others => '0')") }} + if (read = '1') then + raddr_int <= address; + end if; +{{ process_end() }} + ren <= ren_int; {% endmacro %} {{ amm_core() }} -end arch_imp; \ No newline at end of file +end arch_imp; diff --git a/corsair/templates/regmap_verilog.j2 b/corsair/templates/regmap_verilog.j2 index 559754f..98fe8e0 100755 --- a/corsair/templates/regmap_verilog.j2 +++ b/corsair/templates/regmap_verilog.j2 @@ -422,7 +422,7 @@ assign wready = 1'b1; reg {{ range_decl(config['data_width'] - 1) }} rdata_ff; {{ always_begin(sig='rdata_ff', width=config['data_width'], init=read_filler )}} if (ren) begin - case (raddr) + case (raddr_int) {% for reg in rmap %} {{ literal(reg.address, config['address_width']) }}: rdata_ff <= {{ sig_csr_rdata(reg) }}; {% endfor %} diff --git a/corsair/templates/regmap_vhdl.j2 b/corsair/templates/regmap_vhdl.j2 index 642c4dd..f0dc131 100644 --- a/corsair/templates/regmap_vhdl.j2 +++ b/corsair/templates/regmap_vhdl.j2 @@ -532,10 +532,10 @@ wready <= '1'; {% set loop_ns = namespace(first_reg = True) %} {% for reg in rmap %} {% if loop_ns.first_reg %} - if raddr = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} + if raddr_int = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} rdata_ff <= {{ sig_csr_rdata(reg) }}; {% else %} - elsif raddr = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} + elsif raddr_int = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} rdata_ff <= {{ sig_csr_rdata(reg) }}; {% endif %} {% set loop_ns.first_reg = False %} From ed562e090c985b9d5778ec4482e4aaf490f44112 Mon Sep 17 00:00:00 2001 From: ST de Feber Date: Fri, 27 Sep 2024 15:26:15 +0200 Subject: [PATCH 2/2] Fixed reset value in of radd_int in j2 file --- corsair/templates/amm2lb_verilog.j2 | 69 ++++++++++++++++++++++++++++- corsair/templates/regmap_verilog.j2 | 18 ++++++++ corsair/templates/regmap_vhdl.j2 | 25 +++++++++++ 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/corsair/templates/amm2lb_verilog.j2 b/corsair/templates/amm2lb_verilog.j2 index c81fbe1..2292636 100755 --- a/corsair/templates/amm2lb_verilog.j2 +++ b/corsair/templates/amm2lb_verilog.j2 @@ -3,6 +3,71 @@ // Avalon-MM to Local Bus bridge // +{# MACRO #} +{#- vector range for select operations #} +{% macro range(msb, lsb, is_vector=true) %} + {% if is_vector %} + {% if msb == lsb %} +[{{ msb }}] + {%- else %} +[{{ msb }}:{{ lsb }}] + {%- endif %} + {%- endif %} +{%- endmacro %} +{#- literal #} +{% macro literal(val, width=1) %} + {% if width == 1 %} +1'b{{ val }} + {%- else %} +{{ width}}'h{{ '%x' % val }} + {%- endif %} +{%- endmacro %} + +{#- special literal for all zeros #} +{% macro zeros(width=1) %} + {% if width == 1 %} +1'b0 + {%- else %} +{{ width }}'h0 + {%- endif %} +{%- endmacro %} + +{#- special literal for all ones #} +{% macro ones(width=1) %} + {% if width == 1 %} +1'b1 + {%- else %} +{{ "{%d{1'b1}}" % width }} + {%- endif %} +{%- endmacro %} + +{% macro range_decl(msb, is_vector=true) %} + {% if is_vector %} +[{{ msb }}:0] + {%- endif %} +{%- endmacro %} + +{#- 'always' header with reset logic #} +{% macro always_begin(sig='', width=1, init=0) %} + {% set rst_type = config['register_reset']%} + {% if rst_type == 'sync_pos' %} +always @(posedge clk) begin + if (rst) begin + {% elif rst_type == 'sync_neg' %} +always @(posedge clk) begin + if (!rst) begin + {% elif rst_type == 'async_pos' %} +always @(posedge clk or posedge rst) begin + if (rst) begin + {% elif rst_type == 'async_neg' %} +always @(posedge clk or negedge rst) begin + if (!rst) begin + {% endif %} + {{ sig }} <= {{ literal(init, width) }}; + end else +{%- endmacro %} + + module {{ module_name }} #( parameter ADDR_W = {{ config['address_width'] }}, parameter DATA_W = {{ config['data_width'] }}, @@ -78,8 +143,8 @@ wire ren; end end - reg {{ range_decl(config['data_width'] - 1) }} raddr_int; - {{ always_begin(sig='raddr_int', width=config['data_width'], init=read_filler + reg {{ range_decl(config['address_width'] - 1) }} raddr_int; + {{ always_begin(sig='raddr_int', width=config['address_width'], init=0 )}} if (read) begin raddr_int <= address; end diff --git a/corsair/templates/regmap_verilog.j2 b/corsair/templates/regmap_verilog.j2 index 98fe8e0..ff009d4 100755 --- a/corsair/templates/regmap_verilog.j2 +++ b/corsair/templates/regmap_verilog.j2 @@ -420,6 +420,8 @@ assign wready = 1'b1; // Read address decoder //------------------------------------------------------------------------------ reg {{ range_decl(config['data_width'] - 1) }} rdata_ff; + +{% if interface == 'amm' %} {{ always_begin(sig='rdata_ff', width=config['data_width'], init=read_filler )}} if (ren) begin case (raddr_int) @@ -432,6 +434,22 @@ reg {{ range_decl(config['data_width'] - 1) }} rdata_ff; rdata_ff <= {{ literal(read_filler, config['data_width']) }}; end end +{% else %} +{{ always_begin(sig='rdata_ff', width=config['data_width'], init=read_filler +)}} if (ren) begin + case (raddr) +{% for reg in rmap %} + {{ literal(reg.address, config['address_width']) }}: rdata_ff <= {{ sig_csr_rdata(reg) }}; +{% endfor %} + default: rdata_ff <= {{ literal(read_filler, config['data_width']) }}; + endcase + end else begin + rdata_ff <= {{ literal(read_filler, config['data_width']) }}; + end +end +{% endif %} + + assign rdata = rdata_ff; //------------------------------------------------------------------------------ diff --git a/corsair/templates/regmap_vhdl.j2 b/corsair/templates/regmap_vhdl.j2 index f0dc131..0cffc94 100644 --- a/corsair/templates/regmap_vhdl.j2 +++ b/corsair/templates/regmap_vhdl.j2 @@ -527,6 +527,7 @@ wready <= '1'; -------------------------------------------------------------------------------- -- Read address decoder -------------------------------------------------------------------------------- +{% if interface == 'amm' %} {{ process_begin(sig='rdata_ff', width=config['data_width'], init=read_filler)}} if (ren = '1') then {% set loop_ns = namespace(first_reg = True) %} @@ -547,6 +548,30 @@ wready <= '1'; rdata_ff <= {{ literal(read_filler, config['data_width']) }}; {{ literal_comment(read_filler) }} end if; {{ process_end() }} +{% else %} +{{ process_begin(sig='rdata_ff', width=config['data_width'], init=read_filler)}} + if (ren = '1') then +{% set loop_ns = namespace(first_reg = True) %} +{% for reg in rmap %} + {% if loop_ns.first_reg %} + if raddr = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} + rdata_ff <= {{ sig_csr_rdata(reg) }}; + {% else %} + elsif raddr = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} + rdata_ff <= {{ sig_csr_rdata(reg) }}; + {% endif %} + {% set loop_ns.first_reg = False %} +{% endfor %} + else + rdata_ff <= {{ literal(read_filler, config['data_width']) }}; {{ literal_comment(read_filler) }} + end if; + else + rdata_ff <= {{ literal(read_filler, config['data_width']) }}; {{ literal_comment(read_filler) }} + end if; +{{ process_end() }} + +{% endif %} + rdata <= rdata_ff; --------------------------------------------------------------------------------