diff --git a/.github/workflows/test-on-push.yml b/.github/workflows/test-on-push.yml index ed7bae6..6bab4dd 100644 --- a/.github/workflows/test-on-push.yml +++ b/.github/workflows/test-on-push.yml @@ -28,3 +28,9 @@ jobs: - name: Test package run: | pytest -v -n auto + - name: Upload build artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: build-output + path: /tmp diff --git a/corsair/templates/amm2lb_verilog.j2 b/corsair/templates/amm2lb_verilog.j2 index e0dd6e1..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,6 +143,13 @@ wire ren; end end + 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 + 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..ff009d4 100755 --- a/corsair/templates/regmap_verilog.j2 +++ b/corsair/templates/regmap_verilog.j2 @@ -420,6 +420,21 @@ 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) +{% 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 +{% else %} {{ always_begin(sig='rdata_ff', width=config['data_width'], init=read_filler )}} if (ren) begin case (raddr) @@ -432,6 +447,9 @@ reg {{ range_decl(config['data_width'] - 1) }} rdata_ff; 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 642c4dd..0cffc94 100644 --- a/corsair/templates/regmap_vhdl.j2 +++ b/corsair/templates/regmap_vhdl.j2 @@ -527,6 +527,28 @@ 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) %} +{% for reg in rmap %} + {% if loop_ns.first_reg %} + 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_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 %} +{% 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() }} +{% else %} {{ 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 +569,9 @@ wready <= '1'; rdata_ff <= {{ literal(read_filler, config['data_width']) }}; {{ literal_comment(read_filler) }} end if; {{ process_end() }} + +{% endif %} + rdata <= rdata_ff; -------------------------------------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..28a13ef --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "GitPython"] +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py index 6d1d42c..a602c7a 100644 --- a/setup.py +++ b/setup.py @@ -8,11 +8,21 @@ def git_version(version): """Return version with local version identifier.""" import git - repo = git.Repo('.git') + + try: + repo = git.Repo('.git') + except git.NoSuchPathError: + # Not in a git repo, assume install through PyPI / source distribution + return version + repo.git.status() # assert versions are increasing - latest_tag = repo.git.describe( - match='v[0-9]*', tags=True, abbrev=0) + try: + latest_tag = repo.git.describe( + match='v[0-9]*', tags=True, abbrev=0) + except git.exc.GitCommandError: + # No tags found + latest_tag = version assert parse_version(latest_tag) <= parse_version(version), ( latest_tag, version) sha = repo.head.commit.hexsha[:8] diff --git a/tests/hdl/test_rmap/tb_ro.sv b/tests/hdl/test_rmap/tb_ro.sv index 6a82c09..e377cc6 100755 --- a/tests/hdl/test_rmap/tb_ro.sv +++ b/tests/hdl/test_rmap/tb_ro.sv @@ -4,7 +4,8 @@ module tb_ro; // Test environment with DUT and bridge to LocalBus `include "env.svh" - +`define DBG 1 + // Test body int errors = 0; logic [ADDR_W-1:0] addr; @@ -14,23 +15,35 @@ logic [STRB_W-1:0] strb; task test_ro_i; $display("%0t, Start RO+I tests!", $time); addr = CSR_REGRO_ADDR; + `ifdef DBG + $display("address %0x", addr); + `endif // read mst.read(addr, data); if (data[CSR_REGRO_BFI_LSB+:CSR_REGRO_BFI_WIDTH] != 0) + begin errors++; + $display("%0t, Expected 0, got %0x", $time, data); + end // update hardware value @(posedge clk); csr_regro_bfi_in = 100; // read again mst.read(addr, data); if (data[CSR_REGRO_BFI_LSB+:CSR_REGRO_BFI_WIDTH] != 100) + begin errors++; + $display("%0t, Expected 100, got %0x", $time, data); + end // write has no effect data = 200 << CSR_REGRO_BFI_LSB; mst.write(addr, data); mst.read(addr, data); if (data[CSR_REGRO_BFI_LSB+:CSR_REGRO_BFI_WIDTH] != 100) + begin errors++; + $display("%0t, Expected 100, got %0x", $time, data); + end $display("%0t, %0d errors", $time, errors); endtask