diff options
| author | Alejandro Soto <alejandro@34project.org> | 2024-04-27 12:14:41 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2024-04-27 12:14:41 -0600 |
| commit | 50b71c7f0ea2574eb4802e1a12fe8b0920a4ca7f (patch) | |
| tree | 42a0180d2cf67427a3273facca9358aa4ba3f1cc /rtl/axi_timer/axi_timer.sv | |
| parent | 45b5eabe868ac2f8a755379bde07c102caf74afb (diff) | |
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
Diffstat (limited to '')
| -rw-r--r-- | rtl/axi_timer/axi_timer.sv | 125 |
1 files changed, 125 insertions, 0 deletions
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 |
