Skip to content

Commit 24d831d

Browse files
committed
Adding single port axi ram
1 parent ff24688 commit 24d831d

5 files changed

Lines changed: 240 additions & 0 deletions

File tree

logikbench/memory/axiram/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2018 Alex Forencich
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

logikbench/memory/axiram/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-axilite single port SRAM
2+
3+
d274c73cb72fbfd95eb879ae6aa666606c182a6d
4+
5+
https://github.com/alexforencich/verilog-axi

logikbench/memory/axiram/axiram.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from os.path import dirname, abspath
2+
from siliconcompiler.design import DesignSchema
3+
4+
5+
class Axiram(DesignSchema):
6+
def __init__(self):
7+
8+
name = 'axiram'
9+
root = f'{name}_root'
10+
topmodule = 'axil_ram'
11+
source = [f'rtl/axil_ram.v']
12+
13+
# create a Design object
14+
super().__init__(name)
15+
16+
# set data home directory
17+
self.register_package(root, dirname(abspath(__file__)))
18+
19+
# rtl files
20+
fileset = 'rtl'
21+
for item in source:
22+
self.add_file(item, fileset, package=root)
23+
24+
# top module
25+
self.set_topmodule(topmodule, fileset)
26+
27+
28+
if __name__ == "__main__":
29+
d = Axiram()
30+
d.write_fileset(f"{d.name()}.f", fileset="rtl")
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# parameters
2+
set CLK_PERIOD 1000 # clock period, watch the units!
3+
set INPUT_DELAY 0
4+
set OUTPUT_DELAY $CLK_PERIOD
5+
6+
# create a clock
7+
create_clock -name clk -period $CLK_PERIOD clk
8+
9+
# time used by external logic with respect to rising edge
10+
set_input_delay $INPUT_DELAY -clock clk [get_ports addr*]
11+
set_input_delay $INPUT_DELAY -clock clk [get_ports din*]
12+
13+
# time after launching rising edge that output must be ready
14+
set_output_delay $OUTPUT_DELAY -clock clk [get_ports dout*]
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
3+
Copyright (c) 2018 Alex Forencich
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
22+
23+
*/
24+
25+
module axil_ram #
26+
(
27+
// Width of data bus in bits
28+
parameter DATA_WIDTH = 32,
29+
// Width of address bus in bits
30+
parameter ADDR_WIDTH = 16,
31+
// Width of wstrb (width of data bus in words)
32+
parameter STRB_WIDTH = (DATA_WIDTH/8),
33+
// Extra pipeline register on output
34+
parameter PIPELINE_OUTPUT = 0
35+
)
36+
(
37+
input wire clk,
38+
input wire rst,
39+
40+
input wire [ADDR_WIDTH-1:0] s_axil_awaddr,
41+
input wire [2:0] s_axil_awprot,
42+
input wire s_axil_awvalid,
43+
output wire s_axil_awready,
44+
input wire [DATA_WIDTH-1:0] s_axil_wdata,
45+
input wire [STRB_WIDTH-1:0] s_axil_wstrb,
46+
input wire s_axil_wvalid,
47+
output wire s_axil_wready,
48+
output wire [1:0] s_axil_bresp,
49+
output wire s_axil_bvalid,
50+
input wire s_axil_bready,
51+
input wire [ADDR_WIDTH-1:0] s_axil_araddr,
52+
input wire [2:0] s_axil_arprot,
53+
input wire s_axil_arvalid,
54+
output wire s_axil_arready,
55+
output wire [DATA_WIDTH-1:0] s_axil_rdata,
56+
output wire [1:0] s_axil_rresp,
57+
output wire s_axil_rvalid,
58+
input wire s_axil_rready
59+
);
60+
61+
parameter VALID_ADDR_WIDTH = ADDR_WIDTH - $clog2(STRB_WIDTH);
62+
parameter WORD_WIDTH = STRB_WIDTH;
63+
parameter WORD_SIZE = DATA_WIDTH/WORD_WIDTH;
64+
65+
reg mem_wr_en;
66+
reg mem_rd_en;
67+
68+
reg s_axil_awready_reg = 1'b0, s_axil_awready_next;
69+
reg s_axil_wready_reg = 1'b0, s_axil_wready_next;
70+
reg s_axil_bvalid_reg = 1'b0, s_axil_bvalid_next;
71+
reg s_axil_arready_reg = 1'b0, s_axil_arready_next;
72+
reg [DATA_WIDTH-1:0] s_axil_rdata_reg = {DATA_WIDTH{1'b0}}, s_axil_rdata_next;
73+
reg s_axil_rvalid_reg = 1'b0, s_axil_rvalid_next;
74+
reg [DATA_WIDTH-1:0] s_axil_rdata_pipe_reg = {DATA_WIDTH{1'b0}};
75+
reg s_axil_rvalid_pipe_reg = 1'b0;
76+
77+
// (* RAM_STYLE="BLOCK" *)
78+
reg [DATA_WIDTH-1:0] mem[(2**VALID_ADDR_WIDTH)-1:0];
79+
80+
wire [VALID_ADDR_WIDTH-1:0] s_axil_awaddr_valid = s_axil_awaddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
81+
wire [VALID_ADDR_WIDTH-1:0] s_axil_araddr_valid = s_axil_araddr >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
82+
83+
assign s_axil_awready = s_axil_awready_reg;
84+
assign s_axil_wready = s_axil_wready_reg;
85+
assign s_axil_bresp = 2'b00;
86+
assign s_axil_bvalid = s_axil_bvalid_reg;
87+
assign s_axil_arready = s_axil_arready_reg;
88+
assign s_axil_rdata = PIPELINE_OUTPUT ? s_axil_rdata_pipe_reg : s_axil_rdata_reg;
89+
assign s_axil_rresp = 2'b00;
90+
assign s_axil_rvalid = PIPELINE_OUTPUT ? s_axil_rvalid_pipe_reg : s_axil_rvalid_reg;
91+
92+
integer i, j;
93+
94+
initial begin
95+
// two nested loops for smaller number of iterations per loop
96+
// workaround for synthesizer complaints about large loop counts
97+
for (i = 0; i < 2**VALID_ADDR_WIDTH; i = i + 2**(VALID_ADDR_WIDTH/2)) begin
98+
for (j = i; j < i + 2**(VALID_ADDR_WIDTH/2); j = j + 1) begin
99+
mem[j] = 0;
100+
end
101+
end
102+
end
103+
104+
always @* begin
105+
mem_wr_en = 1'b0;
106+
107+
s_axil_awready_next = 1'b0;
108+
s_axil_wready_next = 1'b0;
109+
s_axil_bvalid_next = s_axil_bvalid_reg && !s_axil_bready;
110+
111+
if (s_axil_awvalid && s_axil_wvalid && (!s_axil_bvalid || s_axil_bready) && (!s_axil_awready && !s_axil_wready)) begin
112+
s_axil_awready_next = 1'b1;
113+
s_axil_wready_next = 1'b1;
114+
s_axil_bvalid_next = 1'b1;
115+
116+
mem_wr_en = 1'b1;
117+
end
118+
end
119+
120+
always @(posedge clk) begin
121+
s_axil_awready_reg <= s_axil_awready_next;
122+
s_axil_wready_reg <= s_axil_wready_next;
123+
s_axil_bvalid_reg <= s_axil_bvalid_next;
124+
125+
for (i = 0; i < WORD_WIDTH; i = i + 1) begin
126+
if (mem_wr_en && s_axil_wstrb[i]) begin
127+
mem[s_axil_awaddr_valid][WORD_SIZE*i +: WORD_SIZE] <= s_axil_wdata[WORD_SIZE*i +: WORD_SIZE];
128+
end
129+
end
130+
131+
if (rst) begin
132+
s_axil_awready_reg <= 1'b0;
133+
s_axil_wready_reg <= 1'b0;
134+
s_axil_bvalid_reg <= 1'b0;
135+
end
136+
end
137+
138+
always @* begin
139+
mem_rd_en = 1'b0;
140+
141+
s_axil_arready_next = 1'b0;
142+
s_axil_rvalid_next = s_axil_rvalid_reg && !(s_axil_rready || (PIPELINE_OUTPUT && !s_axil_rvalid_pipe_reg));
143+
144+
if (s_axil_arvalid && (!s_axil_rvalid || s_axil_rready || (PIPELINE_OUTPUT && !s_axil_rvalid_pipe_reg)) && (!s_axil_arready)) begin
145+
s_axil_arready_next = 1'b1;
146+
s_axil_rvalid_next = 1'b1;
147+
148+
mem_rd_en = 1'b1;
149+
end
150+
end
151+
152+
always @(posedge clk) begin
153+
s_axil_arready_reg <= s_axil_arready_next;
154+
s_axil_rvalid_reg <= s_axil_rvalid_next;
155+
156+
if (mem_rd_en) begin
157+
s_axil_rdata_reg <= mem[s_axil_araddr_valid];
158+
end
159+
160+
if (!s_axil_rvalid_pipe_reg || s_axil_rready) begin
161+
s_axil_rdata_pipe_reg <= s_axil_rdata_reg;
162+
s_axil_rvalid_pipe_reg <= s_axil_rvalid_reg;
163+
end
164+
165+
if (rst) begin
166+
s_axil_arready_reg <= 1'b0;
167+
s_axil_rvalid_reg <= 1'b0;
168+
s_axil_rvalid_pipe_reg <= 1'b0;
169+
end
170+
end
171+
172+
endmodule

0 commit comments

Comments
 (0)