summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rtl/axilemu/axilemu.sv70
-rw-r--r--rtl/axilemu/axilemu_if.rdl130
-rw-r--r--rtl/axilemu/mod.mk18
-rw-r--r--rtl/mod.mk2
4 files changed, 219 insertions, 1 deletions
diff --git a/rtl/axilemu/axilemu.sv b/rtl/axilemu/axilemu.sv
new file mode 100644
index 0000000..e58737b
--- /dev/null
+++ b/rtl/axilemu/axilemu.sv
@@ -0,0 +1,70 @@
+module axilemu
+import axilemu_if_pkg::*;
+(
+ input logic clk,
+ rst_n,
+
+ if_axil.s agent,
+ driver,
+
+ output logic irq
+);
+
+ axi4lite_intf #(.ADDR_WIDTH(AXILEMU_IF_MIN_ADDR_WIDTH)) regblock();
+
+ axilemu_if__in_t if_in;
+ axilemu_if__out_t if_out;
+
+ assign agent.rdata = if_out.R.DATA.value;
+ assign agent.bvalid = if_out.B.VALID.value;
+
+ assign if_in.CTRL.BDONE.hwset = agent.bvalid & agent.bready;
+ assign if_in.CTRL.RDONE.hwset = agent.rvalid & agent.rready;
+ assign if_in.CTRL.WVALID.next = agent.wvalid;
+ assign if_in.CTRL.ARVALID.next = agent.arvalid;
+ assign if_in.CTRL.AWVALID.next = agent.awvalid;
+
+ assign if_in.AR.ADDR.next = agent.araddr[31:2];
+ assign if_in.AR.VALID.hwset = agent.arvalid & ~agent.arready & ~if_out.AR.VALID.value;
+
+ assign if_in.AW.ADDR.next = agent.awaddr[31:2];
+ assign if_in.AW.VALID.hwset = agent.awvalid & ~agent.awready & ~if_out.AW.VALID.value;
+
+ assign if_in.W.DATA.next = agent.wdata;
+
+ assign if_in.B.VALID.hwclr = agent.bvalid & agent.bready;
+
+ if_axil2regblock axil2regblock
+ (
+ .axis(driver),
+ .axim(regblock.master)
+ );
+
+ axilemu_if regif
+ (
+ .clk,
+ .arst_n(rst_n),
+ .s_axil(regblock.slave),
+ .hwif_in(if_in),
+ .hwif_out(if_out)
+ );
+
+ always_ff @(posedge clk or negedge rst_n)
+ if (~rst_n) begin
+ irq <= 0;
+
+ agent.rvalid <= 0;
+ agent.wready <= 0;
+ agent.arready <= 0;
+ agent.awready <= 0;
+ end else begin
+ irq <= (if_out.CTRL.ARINT.value & agent.arvalid)
+ | (if_out.CTRL.AWINT.value & agent.awvalid);
+
+ agent.rvalid <= if_out.R.DATA.swmod | (agent.rvalid & ~agent.rready);
+ agent.wready <= agent.wvalid & if_out.W.DATA.swacc;
+ agent.arready <= agent.arvalid & if_out.AR.VALID.swmod;
+ agent.awready <= agent.awvalid & if_out.AW.VALID.swmod;
+ end
+
+endmodule
diff --git a/rtl/axilemu/axilemu_if.rdl b/rtl/axilemu/axilemu_if.rdl
new file mode 100644
index 0000000..99283cf
--- /dev/null
+++ b/rtl/axilemu/axilemu_if.rdl
@@ -0,0 +1,130 @@
+addrmap axilemu_if {
+ name = "AXI-Lite agent emulation interface";
+
+ default hw = w;
+ default sw = r;
+ default regwidth = 32;
+ default precedence = hw;
+
+ reg {
+ name = "Agent control register";
+
+ field {
+ desc = "Enable interrupt on pending read";
+
+ hw = r;
+ sw = rw;
+ } ARINT[0:0] = 0;
+
+ field {
+ desc = "Enable interrupt on pending write";
+
+ hw = r;
+ sw = rw;
+ } AWINT[1:1] = 0;
+
+ field {
+ desc = "Read command is pending";
+ } ARVALID[8:8] = 0;
+
+ field {
+ desc = "Write command is pending";
+ } AWVALID[9:9] = 0;
+
+ field {
+ desc = "Last read data acknowledged";
+
+ hw = na;
+
+ rclr;
+ hwset;
+ } RDONE[10:10] = 0;
+
+ field {
+ desc = "Write data is pending";
+ } WVALID[11:11] = 0;
+
+ field {
+ desc = "Last write response acknowledged";
+
+ hw = na;
+
+ rclr;
+ hwset;
+ } BDONE[12:12] = 0;
+ } CTRL @ 0x00;
+
+ reg {
+ name = "Read command channel";
+
+ field {
+ desc = "Read is pending";
+
+ hw = r;
+
+ rclr;
+ hwset;
+ swmod;
+ } VALID[0:0] = 0;
+
+ field {
+ desc = "Read address";
+ } ADDR[31:2];
+ } AR @ 0x04;
+
+ reg {
+ name = "Write command channel";
+
+ field {
+ desc = "Write is pending";
+
+ hw = r;
+
+ rclr;
+ hwset;
+ swmod;
+ } VALID[0:0] = 0;
+
+ field {
+ desc = "Write address";
+ } ADDR[31:2];
+ } AW @ 0x08;
+
+ reg {
+ name = "Read data channel";
+
+ field {
+ desc = "Read data";
+
+ hw = r;
+ sw = rw;
+
+ swmod;
+ } DATA[31:0];
+ } R @ 0x0c;
+
+ reg {
+ name = "Write data channel";
+
+ field {
+ desc = "Write data";
+
+ swacc;
+ } DATA[31:0];
+ } W @ 0x10;
+
+ reg {
+ name = "Write response channel";
+
+ field {
+ desc = "Valid response";
+
+ hw = r;
+ sw = rw;
+
+ hwclr;
+ woset;
+ } VALID[0:0];
+ } B @ 0x14;
+};
+
diff --git a/rtl/axilemu/mod.mk b/rtl/axilemu/mod.mk
new file mode 100644
index 0000000..60747a7
--- /dev/null
+++ b/rtl/axilemu/mod.mk
@@ -0,0 +1,18 @@
+cores := axilemu_if
+
+define core
+ $(this)/deps := axilemu_if if_common
+
+ $(this)/rtl_top := axilemu
+ $(this)/rtl_dirs := .
+ $(this)/rtl_files := axilemu.sv
+endef
+
+define core/axilemu_if
+ $(this)/hooks := regblock
+
+ $(this)/regblock_rdl := axilemu_if.rdl
+ $(this)/regblock_top := axilemu_if
+ $(this)/regblock_args := --default-reset arst_n
+ $(this)/regblock_cpuif := axi4-lite
+endef
diff --git a/rtl/mod.mk b/rtl/mod.mk
index d1ab444..c7e259a 100644
--- a/rtl/mod.mk
+++ b/rtl/mod.mk
@@ -1,5 +1,5 @@
cores := config debounce intc
-subdirs := cache core dma_axi32 if_common fpu gfx legacy_gfx perf picorv32 pkt_switch smp top wb2axip
+subdirs := axilemu cache core dma_axi32 if_common fpu gfx legacy_gfx perf picorv32 pkt_switch smp top wb2axip
define core/config
$(this)/rtl_include_dirs := .