From 50b71c7f0ea2574eb4802e1a12fe8b0920a4ca7f Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Sat, 27 Apr 2024 12:14:41 -0600 Subject: rtl/axi_timer: initial commit This a buggy timer, imported from https://github.com/astrakhov-design/axi_timer. It will be used for a testbench hello world case --- rtl/axi_timer/axi_bus.sv | 28 +++++++++ rtl/axi_timer/axi_timer.sv | 125 +++++++++++++++++++++++++++++++++++++++++ rtl/axi_timer/axi_timer_top.sv | 45 +++++++++++++++ rtl/axi_timer/mod.mk | 10 ++++ rtl/axi_timer/testbench.py | 0 rtl/mod.mk | 2 +- 6 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 rtl/axi_timer/axi_bus.sv create mode 100644 rtl/axi_timer/axi_timer.sv create mode 100644 rtl/axi_timer/axi_timer_top.sv create mode 100644 rtl/axi_timer/mod.mk create mode 100644 rtl/axi_timer/testbench.py (limited to 'rtl') diff --git a/rtl/axi_timer/axi_bus.sv b/rtl/axi_timer/axi_bus.sv new file mode 100644 index 0000000..f1460ca --- /dev/null +++ b/rtl/axi_timer/axi_bus.sv @@ -0,0 +1,28 @@ +//AXI interface bus +interface axi_bus #( + parameter int unsigned AXI_ADDR_WIDTH = 32, + parameter int unsigned AXI_DATA_WIDTH = 32 + ); + + logic [AXI_ADDR_WIDTH-1:0] ADDR; + logic AVALID; + logic AREADY; + logic AWRITE; + logic WVALID; + logic WREADY; + logic [AXI_DATA_WIDTH-1:0] WDATA; + logic RVALID; + logic RREADY; + logic [AXI_DATA_WIDTH-1:0] RDATA; + + modport Master( + input AREADY, WREADY, RVALID, RDATA, + output ADDR, AVALID, AWRITE, WVALID, WDATA, RREADY + ); + + modport Slave( + input ADDR, AVALID, AWRITE, WVALID, WDATA, RREADY, + output AREADY, WREADY, RVALID, RDATA + ); + +endinterface diff --git a/rtl/axi_timer/axi_timer.sv b/rtl/axi_timer/axi_timer.sv new file mode 100644 index 0000000..80a1805 --- /dev/null +++ b/rtl/axi_timer/axi_timer.sv @@ -0,0 +1,125 @@ +//axi_timer top file + +module axi_timer( + input i_clk, + input i_rst_n, + + axi_bus.Slave axi_slave, + + output logic o_IRQ + ); + +// verilator lint_off CASEINCOMPLETE +// verilator lint_off WIDTHEXPAND +// verilator lint_off WIDTHTRUNC + +enum logic [2:0] { + CR_ADDR = 3'd0, + SR_ADDR = 3'd1, + PERIOD_ADDR = 3'd2, + COUNTER_ADDR = 3'd3, + IRQ_CNT_ADDR = 3'd4 +} address_map; + +/*Register map for axi_timer */ +//CR register +logic enable; +//SR register +logic irq; +//PERIOD register +logic [31:0] period; +//COUNTER register +logic [31:0] counter; +//IRQ_CNT register +logic [31:0] irq_cnt; + +/* Native interface for access to register */ +logic addr_valid; +logic addr; +logic addr_ready; +logic addr_write; + +logic write_valid; +logic [31:0] wdata; +logic write_ready; + +logic read_valid; +logic [31:0] rdata; +logic read_ready; + +/* Address section */ +assign addr_valid = axi_slave.AVALID; +assign addr_write = axi_slave.AWRITE; +assign axi_slave.AREADY = addr_ready; + +always_ff @ (posedge i_clk, negedge i_rst_n) + if(!i_rst_n) + addr_ready <= 1'b0; + else if(addr_valid & addr_write) + addr_ready <= 1'b1; + else + addr_ready <= 1'b0; + +always_ff @ (posedge i_clk, negedge i_rst_n) + if(!i_rst_n) + addr <= 'h0; + else if(addr_ready & addr_write) + addr <= axi_slave.ADDR; + +/*Write section */ +assign write_valid = axi_slave.WVALID; +assign axi_slave.WREADY = write_ready; +assign wdata = axi_slave.WDATA; + +always_ff @ (posedge i_clk, negedge i_rst_n) + if(!i_rst_n) + write_ready <= 1'b0; + else if(write_valid) + write_ready <= 1'b1; + else + write_ready <= 1'b0; + +/* registers write logic */ +always_ff @ (posedge i_clk, negedge i_rst_n) + if(!i_rst_n) begin + enable <= 1'b0; + period <= 32'd0; + irq_cnt <= 32'd0; + end + else if(write_valid) begin + case(addr) + CR_ADDR: enable <= wdata[0]; + PERIOD_ADDR: counter <= wdata; + IRQ_CNT_ADDR: irq_cnt <= wdata; + endcase + end + +/*Read section */ +assign axi_slave.RVALID = read_valid; +assign read_ready = axi_slave.RREADY; +assign axi_slave.RDATA = rdata; + +always_ff @ (posedge i_clk, negedge i_rst_n) + if(!i_rst_n) begin + rdata <= 32'd0; + read_valid <= 1'b0; + end + else if(read_ready) begin + read_valid <= 1'b1; + case(addr) + CR_ADDR: rdata <= {31'd0, enable}; + SR_ADDR: rdata <= {31'd0, irq}; + PERIOD_ADDR: rdata <= period; + COUNTER_ADDR: rdata <= counter; + IRQ_CNT_ADDR: rdata <= irq_cnt; + endcase + end + else begin + read_valid <= 1'b0; + rdata <= 32'd0; + end + + + + +endmodule //axi_timer diff --git a/rtl/axi_timer/axi_timer_top.sv b/rtl/axi_timer/axi_timer_top.sv new file mode 100644 index 0000000..6bd0e2a --- /dev/null +++ b/rtl/axi_timer/axi_timer_top.sv @@ -0,0 +1,45 @@ +module axi_timer_top +( + input logic clk, + rst_n, + + input logic[31:0] addr, + input logic avalid, + input logic awrite, + output logic aready, + + input logic wvalid, + input logic[31:0] wdata, + output logic wready, + + input logic rready, + output logic[31:0] rdata, + output logic rvalid, + + output logic irq +); + + axi_bus axi(); + + assign axi.Master.ADDR = addr; + assign axi.Master.AVALID = avalid; + assign axi.Master.AWRITE = awrite; + assign aready = axi.Master.AREADY; + + assign axi.Master.WVALID = wvalid; + assign axi.Master.WDATA = wdata; + assign wready = axi.Master.WREADY; + + assign axi.Master.RREADY = rready; + assign rdata = axi.Master.RDATA; + assign rvalid = axi.Master.RVALID; + + axi_timer timer + ( + .i_clk(clk), + .i_rst_n(rst_n), + .o_IRQ(irq), + .axi_slave(axi.Slave) + ); + +endmodule diff --git a/rtl/axi_timer/mod.mk b/rtl/axi_timer/mod.mk new file mode 100644 index 0000000..2efe0f4 --- /dev/null +++ b/rtl/axi_timer/mod.mk @@ -0,0 +1,10 @@ +define core + $(this)/targets := sim test + + $(this)/rtl_top := axi_timer_top + $(this)/rtl_dirs := . + $(this)/rtl_files := axi_bus.sv axi_timer_top.sv + + $(this)/cocotb_paths := . + $(this)/cocotb_modules := testbench +endef diff --git a/rtl/axi_timer/testbench.py b/rtl/axi_timer/testbench.py new file mode 100644 index 0000000..e69de29 diff --git a/rtl/mod.mk b/rtl/mod.mk index 0360207..be9cb44 100644 --- a/rtl/mod.mk +++ b/rtl/mod.mk @@ -1,5 +1,5 @@ cores := config debounce intc -subdirs := cache core dma_axi32 fpu gfx perf picorv32 smp top wb2axip +subdirs := axi_timer cache core dma_axi32 fpu gfx perf picorv32 smp top wb2axip define core/config $(this)/rtl_include_dirs := . -- cgit v1.2.3