From 321d8a6cd1cdfd4d0e6217e351b6d111acffa6e0 Mon Sep 17 00:00:00 2001 From: Alex Mykyta Date: Thu, 27 Jan 2022 22:04:17 -0800 Subject: [PATCH] Add passthrough CPUIF --- peakrdl/regblock/cpuif/apb3/apb3_tmpl.sv | 4 - peakrdl/regblock/cpuif/base.py | 2 +- peakrdl/regblock/cpuif/base_tmpl.sv | 2 - .../regblock/cpuif/passthrough/__init__.py | 19 ++++ .../cpuif/passthrough/passthrough_tmpl.sv | 9 ++ peakrdl/regblock/exporter.py | 1 - peakrdl/regblock/module_tmpl.sv | 6 +- test/lib/cpuifs/apb3/tb_inst.sv | 2 +- test/lib/cpuifs/passthrough/__init__.py | 10 ++ .../cpuifs/passthrough/passthrough_driver.sv | 92 +++++++++++++++++++ test/lib/cpuifs/passthrough/tb_inst.sv | 26 ++++++ test/lib/test_params.py | 2 + 12 files changed, 161 insertions(+), 14 deletions(-) delete mode 100644 peakrdl/regblock/cpuif/base_tmpl.sv create mode 100644 peakrdl/regblock/cpuif/passthrough/__init__.py create mode 100644 peakrdl/regblock/cpuif/passthrough/passthrough_tmpl.sv create mode 100644 test/lib/cpuifs/passthrough/__init__.py create mode 100644 test/lib/cpuifs/passthrough/passthrough_driver.sv create mode 100644 test/lib/cpuifs/passthrough/tb_inst.sv diff --git a/peakrdl/regblock/cpuif/apb3/apb3_tmpl.sv b/peakrdl/regblock/cpuif/apb3/apb3_tmpl.sv index c7bc6d0..983f337 100644 --- a/peakrdl/regblock/cpuif/apb3/apb3_tmpl.sv +++ b/peakrdl/regblock/cpuif/apb3/apb3_tmpl.sv @@ -1,6 +1,3 @@ -{% extends "cpuif/base_tmpl.sv" %} - -{% block body %} // Request logic is_active; always_ff {{get_always_ff_event(cpuif.reset)}} begin @@ -36,4 +33,3 @@ end assign {{cpuif.signal("pready")}} = cpuif_rd_ack | cpuif_wr_ack; assign {{cpuif.signal("prdata")}} = cpuif_rd_data; assign {{cpuif.signal("pslverr")}} = cpuif_rd_err | cpuif_wr_err; -{%- endblock body%} diff --git a/peakrdl/regblock/cpuif/base.py b/peakrdl/regblock/cpuif/base.py index db5a8c4..0418260 100644 --- a/peakrdl/regblock/cpuif/base.py +++ b/peakrdl/regblock/cpuif/base.py @@ -7,7 +7,7 @@ if TYPE_CHECKING: from systemrdl import SignalNode class CpuifBase: - template_path = "cpuif/base_tmpl.sv" + template_path = "" def __init__(self, exp:'RegblockExporter', cpuif_reset:Optional['SignalNode'], data_width:int=32, addr_width:int=32): self.exp = exp diff --git a/peakrdl/regblock/cpuif/base_tmpl.sv b/peakrdl/regblock/cpuif/base_tmpl.sv deleted file mode 100644 index 0fe2e30..0000000 --- a/peakrdl/regblock/cpuif/base_tmpl.sv +++ /dev/null @@ -1,2 +0,0 @@ -{%- block body %} -{%- endblock %} diff --git a/peakrdl/regblock/cpuif/passthrough/__init__.py b/peakrdl/regblock/cpuif/passthrough/__init__.py new file mode 100644 index 0000000..5cb9a0d --- /dev/null +++ b/peakrdl/regblock/cpuif/passthrough/__init__.py @@ -0,0 +1,19 @@ +from ..base import CpuifBase + +class PassthroughCpuif(CpuifBase): + template_path = "cpuif/passthrough/passthrough_tmpl.sv" + + @property + def port_declaration(self) -> str: + lines = [ + "input wire s_cpuif_req", + "input wire s_cpuif_req_is_wr", + f"input wire [{self.addr_width-1}:0] s_cpuif_addr", + f"input wire [{self.data_width-1}:0] s_cpuif_wr_data", + "output wire s_cpuif_rd_ack", + "output wire s_cpuif_rd_err", + f"output wire [{self.data_width-1}:0] s_cpuif_rd_data", + "output wire s_cpuif_wr_ack", + "output wire s_cpuif_wr_err", + ] + return ",\n".join(lines) diff --git a/peakrdl/regblock/cpuif/passthrough/passthrough_tmpl.sv b/peakrdl/regblock/cpuif/passthrough/passthrough_tmpl.sv new file mode 100644 index 0000000..d291496 --- /dev/null +++ b/peakrdl/regblock/cpuif/passthrough/passthrough_tmpl.sv @@ -0,0 +1,9 @@ +assign cpuif_req = s_cpuif_req; +assign cpuif_req_is_wr = s_cpuif_req_is_wr; +assign cpuif_addr = s_cpuif_addr; +assign cpuif_wr_data = s_cpuif_wr_data; +assign s_cpuif_rd_ack = cpuif_rd_ack; +assign s_cpuif_rd_err = cpuif_rd_err; +assign s_cpuif_rd_data = cpuif_rd_data; +assign s_cpuif_wr_ack = cpuif_wr_ack; +assign s_cpuif_wr_err = cpuif_wr_err; diff --git a/peakrdl/regblock/exporter.py b/peakrdl/regblock/exporter.py index f64e75e..2f5dc20 100644 --- a/peakrdl/regblock/exporter.py +++ b/peakrdl/regblock/exporter.py @@ -106,7 +106,6 @@ class RegblockExporter: context = { "module_name": module_name, "user_out_of_hier_signals": scanner.out_of_hier_signals.values(), - "interrupts": [], # TODO: "cpuif": self.cpuif, "hwif": self.hwif, "get_resetsignal": self.dereferencer.get_resetsignal, diff --git a/peakrdl/regblock/module_tmpl.sv b/peakrdl/regblock/module_tmpl.sv index 92b4912..32f2f4d 100644 --- a/peakrdl/regblock/module_tmpl.sv +++ b/peakrdl/regblock/module_tmpl.sv @@ -11,10 +11,6 @@ module {{module_name}} ( {%- endif %} {%- endfor %} - {%- for interrupt in interrupts %} - // TODO: - {%- endfor %} - {{cpuif.port_declaration|indent(8)}} {%- if hwif.has_input_struct or hwif.has_output_struct %},{% endif %} @@ -30,8 +26,8 @@ module {{module_name}} ( logic [{{cpuif.data_width-1}}:0] cpuif_wr_data; logic cpuif_rd_ack; - logic [{{cpuif.data_width-1}}:0] cpuif_rd_data; logic cpuif_rd_err; + logic [{{cpuif.data_width-1}}:0] cpuif_rd_data; logic cpuif_wr_ack; logic cpuif_wr_err; diff --git a/test/lib/cpuifs/apb3/tb_inst.sv b/test/lib/cpuifs/apb3/tb_inst.sv index 7c3662d..aec79b1 100644 --- a/test/lib/cpuifs/apb3/tb_inst.sv +++ b/test/lib/cpuifs/apb3/tb_inst.sv @@ -6,7 +6,7 @@ apb3_intf #( apb3_intf_driver #( .DATA_WIDTH({{exporter.cpuif.data_width}}), .ADDR_WIDTH({{exporter.cpuif.addr_width}}) -) cpuif( +) cpuif ( .clk(clk), .rst(rst), .m_apb(s_apb) diff --git a/test/lib/cpuifs/passthrough/__init__.py b/test/lib/cpuifs/passthrough/__init__.py new file mode 100644 index 0000000..4883d70 --- /dev/null +++ b/test/lib/cpuifs/passthrough/__init__.py @@ -0,0 +1,10 @@ +from ..base import CpuifTestMode + +from peakrdl.regblock.cpuif.passthrough import PassthroughCpuif + +class Passthrough(CpuifTestMode): + cpuif_cls = PassthroughCpuif + tb_files = [ + "passthrough_driver.sv", + ] + tb_template = "tb_inst.sv" diff --git a/test/lib/cpuifs/passthrough/passthrough_driver.sv b/test/lib/cpuifs/passthrough/passthrough_driver.sv new file mode 100644 index 0000000..8be5444 --- /dev/null +++ b/test/lib/cpuifs/passthrough/passthrough_driver.sv @@ -0,0 +1,92 @@ +interface passthrough_driver #( + parameter DATA_WIDTH = 32, + parameter ADDR_WIDTH = 32 + )( + input wire clk, + input wire rst, + + output logic m_cpuif_req, + output logic m_cpuif_req_is_wr, + output logic [ADDR_WIDTH-1:0] m_cpuif_addr, + output logic [DATA_WIDTH-1:0] m_cpuif_wr_data, + input wire m_cpuif_rd_ack, + input wire m_cpuif_rd_err, + input wire [DATA_WIDTH-1:0] m_cpuif_rd_data, + input wire m_cpuif_wr_ack, + input wire m_cpuif_wr_err + ); + + timeunit 1ps; + timeprecision 1ps; + + default clocking cb @(posedge clk); + default input #1step output #1; + output m_cpuif_req; + output m_cpuif_req_is_wr; + output m_cpuif_addr; + output m_cpuif_wr_data; + input m_cpuif_rd_ack; + input m_cpuif_rd_err; + input m_cpuif_rd_data; + input m_cpuif_wr_ack; + input m_cpuif_wr_err; + endclocking + + task reset(); + cb.m_cpuif_req <= '0; + cb.m_cpuif_req_is_wr <= '0; + cb.m_cpuif_addr <= '0; + cb.m_cpuif_wr_data <= '0; + endtask + + task write(logic [ADDR_WIDTH-1:0] addr, logic [DATA_WIDTH-1:0] data); + ##0; + + // Initiate transfer + cb.m_cpuif_req <= '1; + cb.m_cpuif_req_is_wr <= '1; + cb.m_cpuif_addr <= addr; + cb.m_cpuif_wr_data <= data; + @(cb); + reset(); + + // Wait for response + while(cb.m_cpuif_wr_ack !== 1'b1) @(cb); + reset(); + endtask + + task read(logic [ADDR_WIDTH-1:0] addr, output logic [DATA_WIDTH-1:0] data); + ##0; + + // Initiate transfer + cb.m_cpuif_req <= '1; + cb.m_cpuif_req_is_wr <= '0; + cb.m_cpuif_addr <= addr; + @(cb); + reset(); + + // Wait for response + while(cb.m_cpuif_rd_ack !== 1'b1) @(cb); + assert(!$isunknown(cb.m_cpuif_rd_data)) else $error("Read from 0x%0x returned X's on m_cpuif_rd_data", addr); + data = cb.m_cpuif_rd_data; + reset(); + endtask + + task assert_read(logic [ADDR_WIDTH-1:0] addr, logic [DATA_WIDTH-1:0] expected_data, logic [DATA_WIDTH-1:0] mask = '1); + logic [DATA_WIDTH-1:0] data; + read(addr, data); + data &= mask; + assert(data == expected_data) else $error("Read from 0x%x returned 0x%x. Expected 0x%x", addr, data, expected_data); + endtask + + initial begin + reset(); + end + + initial forever begin + @cb; + if(!rst) assert(!$isunknown(cb.m_cpuif_rd_ack)) else $error("Saw X on m_cpuif_rd_ack!"); + if(!rst) assert(!$isunknown(cb.m_cpuif_wr_ack)) else $error("Saw X on m_cpuif_wr_ack!"); + end + +endinterface diff --git a/test/lib/cpuifs/passthrough/tb_inst.sv b/test/lib/cpuifs/passthrough/tb_inst.sv new file mode 100644 index 0000000..a1fdc57 --- /dev/null +++ b/test/lib/cpuifs/passthrough/tb_inst.sv @@ -0,0 +1,26 @@ +{% sv_line_anchor %} +wire s_cpuif_req; +wire s_cpuif_req_is_wr; +wire [{{exporter.cpuif.addr_width-1}}:0] s_cpuif_addr; +wire [{{exporter.cpuif.data_width-1}}:0] s_cpuif_wr_data; +wire s_cpuif_rd_ack; +wire s_cpuif_rd_err; +wire [{{exporter.cpuif.data_width-1}}:0] s_cpuif_rd_data; +wire s_cpuif_wr_ack; +wire s_cpuif_wr_err; +passthrough_driver #( + .DATA_WIDTH({{exporter.cpuif.data_width}}), + .ADDR_WIDTH({{exporter.cpuif.addr_width}}) +) cpuif ( + .clk(clk), + .rst(rst), + .m_cpuif_req(s_cpuif_req), + .m_cpuif_req_is_wr(s_cpuif_req_is_wr), + .m_cpuif_addr(s_cpuif_addr), + .m_cpuif_wr_data(s_cpuif_wr_data), + .m_cpuif_rd_ack(s_cpuif_rd_ack), + .m_cpuif_rd_err(s_cpuif_rd_err), + .m_cpuif_rd_data(s_cpuif_rd_data), + .m_cpuif_wr_ack(s_cpuif_wr_ack), + .m_cpuif_wr_err(s_cpuif_wr_err) +); diff --git a/test/lib/test_params.py b/test/lib/test_params.py index 8720d7d..6f18685 100644 --- a/test/lib/test_params.py +++ b/test/lib/test_params.py @@ -1,11 +1,13 @@ from itertools import product from .cpuifs.apb3 import APB3, FlatAPB3 +from .cpuifs.passthrough import Passthrough all_cpuif = [ APB3(), FlatAPB3(), + Passthrough(), ] def get_permutations(spec):