prerequisites for building yosys:
$ yosys_deps="build-essential clang bison flex libreadline-dev gawk
- tcl-dev libffi-dev git mercurial graphviz xdot pkg-config"
+ tcl-dev libffi-dev git mercurial graphviz xdot pkg-config python"
$ sudo apt-get install $yosys_deps
There are also pre-compiled Yosys binary packages for Ubuntu and Win32 as well
--- /dev/null
+brams_init.mk
+brams_init_*.vh
OBJS += techlibs/xilinx/synth_xilinx.o
+GENFILES += techlibs/xilinx/brams_init_36.vh
+GENFILES += techlibs/xilinx/brams_init_32.vh
+GENFILES += techlibs/xilinx/brams_init_18.vh
+GENFILES += techlibs/xilinx/brams_init_16.vh
+
+EXTRA_OBJS += techlibs/xilinx/brams_init.mk
+.SECONDARY: techlibs/xilinx/brams_init.mk
+
+techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py
+ cd techlibs/xilinx && python brams_init.py
+ touch techlibs/xilinx/brams_init.mk
+
+techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk
+techlibs/xilinx/brams_init_32.vh: techlibs/xilinx/brams_init.mk
+techlibs/xilinx/brams_init_18.vh: techlibs/xilinx/brams_init.mk
+techlibs/xilinx/brams_init_16.vh: techlibs/xilinx/brams_init.mk
+
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_map.v))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_init_18.vh))
+$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_init_16.vh))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_bb.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
bram $__XILINX_RAMB36_SDP
+ init 1
abits 9
dbits 72
groups 2
endbram
bram $__XILINX_RAMB18_SDP
+ init 1
abits 9
dbits 36
groups 2
endbram
bram $__XILINX_RAMB36_TDP
+ init 1
abits 10 @a10d36
dbits 36 @a10d36
abits 11 @a11d18
endbram
bram $__XILINX_RAMB18_TDP
+ init 1
abits 10 @a10d18
dbits 18 @a10d18
abits 11 @a11d9
--- /dev/null
+#!/usr/bin/python
+
+from __future__ import division
+from __future__ import print_function
+
+with open("brams_init_18.vh", "w") as f:
+ for i in range(8):
+ init_snippets = ["INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
+ for k in range(4, 256, 4):
+ init_snippets[k] = "\n " + init_snippets[k]
+ print(".INITP_%02X({%s})," % (i, ", ".join(init_snippets)), file=f)
+ for i in range(64):
+ init_snippets = ["INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)]
+ for k in range(4, 32, 4):
+ init_snippets[k] = "\n " + init_snippets[k]
+ print(".INIT_%02X({%s})," % (i, ", ".join(init_snippets)), file=f)
+
+with open("brams_init_36.vh", "w") as f:
+ for i in range(16):
+ init_snippets = ["INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
+ for k in range(4, 256, 4):
+ init_snippets[k] = "\n " + init_snippets[k]
+ print(".INITP_%02X({%s})," % (i, ", ".join(init_snippets)), file=f)
+ for i in range(128):
+ init_snippets = ["INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)]
+ for k in range(4, 32, 4):
+ init_snippets[k] = "\n " + init_snippets[k]
+ print(".INIT_%02X({%s})," % (i, ", ".join(init_snippets)), file=f)
+
+with open("brams_init_16.vh", "w") as f:
+ for i in range(64):
+ print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
+
+with open("brams_init_32.vh", "w") as f:
+ for i in range(128):
+ print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
+
module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
+ parameter [36863:0] INIT = 36864'bx;
input CLK2;
input CLK3;
.WRITE_MODE_B("READ_FIRST"),
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
+ `include "brams_init_36.vh"
.SIM_DEVICE("7SERIES")
) _TECHMAP_REPLACE_ (
.DOBDO(DO[63:32]),
module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
+ parameter [18431:0] INIT = 18432'bx;
input CLK2;
input CLK3;
.WRITE_MODE_B("READ_FIRST"),
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
+ `include "brams_init_18.vh"
.SIM_DEVICE("7SERIES")
) _TECHMAP_REPLACE_ (
.DOBDO(DO[31:16]),
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
+ parameter [36863:0] INIT = 36864'bx;
input CLK2;
input CLK3;
assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
- RAMB36E1 #(
- .RAM_MODE("TDP"),
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DIADI(32'd0),
- .DIPADIP(4'd0),
- .DOADO(DO[31:0]),
- .DOPADOP(DOP[3:0]),
- .ADDRARDADDR(A1ADDR_16),
- .CLKARDCLK(CLK2),
- .ENARDEN(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(4'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_16),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_8)
- );
+ generate if (CFG_DBITS > 8) begin
+ RAMB36E1 #(
+ .RAM_MODE("TDP"),
+ .READ_WIDTH_A(CFG_DBITS),
+ .READ_WIDTH_B(CFG_DBITS),
+ .WRITE_WIDTH_A(CFG_DBITS),
+ .WRITE_WIDTH_B(CFG_DBITS),
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ .IS_CLKARDCLK_INVERTED(!CLKPOL2),
+ .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
+ `include "brams_init_36.vh"
+ .SIM_DEVICE("7SERIES")
+ ) _TECHMAP_REPLACE_ (
+ .DIADI(32'd0),
+ .DIPADIP(4'd0),
+ .DOADO(DO[31:0]),
+ .DOPADOP(DOP[3:0]),
+ .ADDRARDADDR(A1ADDR_16),
+ .CLKARDCLK(CLK2),
+ .ENARDEN(|1),
+ .REGCEAREGCE(|1),
+ .RSTRAMARSTRAM(|0),
+ .RSTREGARSTREG(|0),
+ .WEA(4'b0),
+
+ .DIBDI(DI),
+ .DIPBDIP(DIP),
+ .DOBDO(DOBDO),
+ .DOPBDOP(DOPBDOP),
+ .ADDRBWRADDR(B1ADDR_16),
+ .CLKBWRCLK(CLK3),
+ .ENBWREN(|1),
+ .REGCEB(|0),
+ .RSTRAMB(|0),
+ .RSTREGB(|0),
+ .WEBWE(B1EN_8)
+ );
+ end else begin
+ RAMB36E1 #(
+ .RAM_MODE("TDP"),
+ .READ_WIDTH_A(CFG_DBITS),
+ .READ_WIDTH_B(CFG_DBITS),
+ .WRITE_WIDTH_A(CFG_DBITS),
+ .WRITE_WIDTH_B(CFG_DBITS),
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ .IS_CLKARDCLK_INVERTED(!CLKPOL2),
+ .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
+ `include "brams_init_32.vh"
+ .SIM_DEVICE("7SERIES")
+ ) _TECHMAP_REPLACE_ (
+ .DIADI(32'd0),
+ .DIPADIP(4'd0),
+ .DOADO(DO[31:0]),
+ .DOPADOP(DOP[3:0]),
+ .ADDRARDADDR(A1ADDR_16),
+ .CLKARDCLK(CLK2),
+ .ENARDEN(|1),
+ .REGCEAREGCE(|1),
+ .RSTRAMARSTRAM(|0),
+ .RSTREGARSTREG(|0),
+ .WEA(4'b0),
+
+ .DIBDI(DI),
+ .DIPBDIP(DIP),
+ .DOBDO(DOBDO),
+ .DOPBDOP(DOPBDOP),
+ .ADDRBWRADDR(B1ADDR_16),
+ .CLKBWRCLK(CLK3),
+ .ENBWREN(|1),
+ .REGCEB(|0),
+ .RSTRAMB(|0),
+ .RSTREGB(|0),
+ .WEBWE(B1EN_8)
+ );
+ end endgenerate
endmodule
// ------------------------------------------------------------------------
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
+ parameter [18431:0] INIT = 18432'bx;
input CLK2;
input CLK3;
assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
- RAMB18E1 #(
- .RAM_MODE("TDP"),
- .READ_WIDTH_A(CFG_DBITS),
- .READ_WIDTH_B(CFG_DBITS),
- .WRITE_WIDTH_A(CFG_DBITS),
- .WRITE_WIDTH_B(CFG_DBITS),
- .WRITE_MODE_A("READ_FIRST"),
- .WRITE_MODE_B("READ_FIRST"),
- .IS_CLKARDCLK_INVERTED(!CLKPOL2),
- .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
- .SIM_DEVICE("7SERIES")
- ) _TECHMAP_REPLACE_ (
- .DIADI(16'b0),
- .DIPADIP(2'b0),
- .DOADO(DO),
- .DOPADOP(DOP),
- .ADDRARDADDR(A1ADDR_14),
- .CLKARDCLK(CLK2),
- .ENARDEN(|1),
- .REGCEAREGCE(|1),
- .RSTRAMARSTRAM(|0),
- .RSTREGARSTREG(|0),
- .WEA(2'b0),
-
- .DIBDI(DI),
- .DIPBDIP(DIP),
- .DOBDO(DOBDO),
- .DOPBDOP(DOPBDOP),
- .ADDRBWRADDR(B1ADDR_14),
- .CLKBWRCLK(CLK3),
- .ENBWREN(|1),
- .REGCEB(|0),
- .RSTRAMB(|0),
- .RSTREGB(|0),
- .WEBWE(B1EN_4)
- );
+ generate if (CFG_DBITS > 8) begin
+ RAMB18E1 #(
+ .RAM_MODE("TDP"),
+ .READ_WIDTH_A(CFG_DBITS),
+ .READ_WIDTH_B(CFG_DBITS),
+ .WRITE_WIDTH_A(CFG_DBITS),
+ .WRITE_WIDTH_B(CFG_DBITS),
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ .IS_CLKARDCLK_INVERTED(!CLKPOL2),
+ .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
+ `include "brams_init_18.vh"
+ .SIM_DEVICE("7SERIES")
+ ) _TECHMAP_REPLACE_ (
+ .DIADI(16'b0),
+ .DIPADIP(2'b0),
+ .DOADO(DO),
+ .DOPADOP(DOP),
+ .ADDRARDADDR(A1ADDR_14),
+ .CLKARDCLK(CLK2),
+ .ENARDEN(|1),
+ .REGCEAREGCE(|1),
+ .RSTRAMARSTRAM(|0),
+ .RSTREGARSTREG(|0),
+ .WEA(2'b0),
+
+ .DIBDI(DI),
+ .DIPBDIP(DIP),
+ .DOBDO(DOBDO),
+ .DOPBDOP(DOPBDOP),
+ .ADDRBWRADDR(B1ADDR_14),
+ .CLKBWRCLK(CLK3),
+ .ENBWREN(|1),
+ .REGCEB(|0),
+ .RSTRAMB(|0),
+ .RSTREGB(|0),
+ .WEBWE(B1EN_4)
+ );
+ end else begin
+ RAMB18E1 #(
+ .RAM_MODE("TDP"),
+ .READ_WIDTH_A(CFG_DBITS),
+ .READ_WIDTH_B(CFG_DBITS),
+ .WRITE_WIDTH_A(CFG_DBITS),
+ .WRITE_WIDTH_B(CFG_DBITS),
+ .WRITE_MODE_A("READ_FIRST"),
+ .WRITE_MODE_B("READ_FIRST"),
+ .IS_CLKARDCLK_INVERTED(!CLKPOL2),
+ .IS_CLKBWRCLK_INVERTED(!CLKPOL3),
+ `include "brams_init_16.vh"
+ .SIM_DEVICE("7SERIES")
+ ) _TECHMAP_REPLACE_ (
+ .DIADI(16'b0),
+ .DIPADIP(2'b0),
+ .DOADO(DO),
+ .DOPADOP(DOP),
+ .ADDRARDADDR(A1ADDR_14),
+ .CLKARDCLK(CLK2),
+ .ENARDEN(|1),
+ .REGCEAREGCE(|1),
+ .RSTRAMARSTRAM(|0),
+ .RSTREGARSTREG(|0),
+ .WEA(2'b0),
+
+ .DIBDI(DI),
+ .DIPBDIP(DIP),
+ .DOBDO(DOBDO),
+ .DOPBDOP(DOPBDOP),
+ .ADDRBWRADDR(B1ADDR_14),
+ .CLKBWRCLK(CLK3),
+ .ENBWREN(|1),
+ .REGCEB(|0),
+ .RSTRAMB(|0),
+ .RSTREGB(|0),
+ .WEBWE(B1EN_4)
+ );
+ end endgenerate
endmodule
input [ABITS-1:0] RD_ADDR,
output [DBITS-1:0] RD_DATA
);
+ localparam [ABITS-1:0] INIT_ADDR_0 = 1234;
+ localparam [ABITS-1:0] INIT_ADDR_1 = 4321;
+ localparam [ABITS-1:0] INIT_ADDR_2 = 2**ABITS-1;
+ localparam [ABITS-1:0] INIT_ADDR_3 = (2**ABITS-1) / 2;
+
+ localparam [DBITS-1:0] INIT_DATA_0 = 128'h 51e152a7300e309ccb8cd06d34558f49;
+ localparam [DBITS-1:0] INIT_DATA_1 = 128'h 07b1fe94a530ddf3027520f9d23ab43e;
+ localparam [DBITS-1:0] INIT_DATA_2 = 128'h 3cedc6de43ef3f607af3193658d0eb0b;
+ localparam [DBITS-1:0] INIT_DATA_3 = 128'h f6bc5514a8abf1e2810df966bcc13b46;
+
reg [DBITS-1:0] memory [0:2**ABITS-1];
reg [ABITS-1:0] RD_ADDR_BUF;
reg [DBITS-1:0] RD_DATA_BUF;
+ initial begin
+ memory[INIT_ADDR_0] <= INIT_DATA_0;
+ memory[INIT_ADDR_1] <= INIT_DATA_1;
+ memory[INIT_ADDR_2] <= INIT_DATA_2;
+ memory[INIT_ADDR_3] <= INIT_DATA_3;
+ end
+
always @(posedge clk) begin
if (WR_EN) memory[WR_ADDR] <= WR_DATA;
RD_ADDR_BUF <= RD_ADDR;
reg [ABITS-1:0] RD_ADDR;
wire [DBITS-1:0] RD_DATA;
+ localparam [ABITS-1:0] INIT_ADDR_0 = 1234;
+ localparam [ABITS-1:0] INIT_ADDR_1 = 4321;
+ localparam [ABITS-1:0] INIT_ADDR_2 = 2**ABITS-1;
+ localparam [ABITS-1:0] INIT_ADDR_3 = (2**ABITS-1) / 2;
+
+ localparam [DBITS-1:0] INIT_DATA_0 = 128'h 51e152a7300e309ccb8cd06d34558f49;
+ localparam [DBITS-1:0] INIT_DATA_1 = 128'h 07b1fe94a530ddf3027520f9d23ab43e;
+ localparam [DBITS-1:0] INIT_DATA_2 = 128'h 3cedc6de43ef3f607af3193658d0eb0b;
+ localparam [DBITS-1:0] INIT_DATA_3 = 128'h f6bc5514a8abf1e2810df966bcc13b46;
+
bram1 #(
// .ABITS(ABITS),
// .DBITS(DBITS),
// $dumpfile("testbench.vcd");
// $dumpvars(0, bram1_tb);
+ memory[INIT_ADDR_0] = INIT_DATA_0;
+ memory[INIT_ADDR_1] = INIT_DATA_1;
+ memory[INIT_ADDR_2] = INIT_DATA_2;
+ memory[INIT_ADDR_3] = INIT_DATA_3;
+
xorshift64_next;
xorshift64_next;
xorshift64_next;
clk <= 0;
for (i = 0; i < 512; i = i+1) begin
- if (DBITS > 64)
- WR_DATA <= (xorshift64_state << (DBITS-64)) ^ xorshift64_state;
- else
- WR_DATA <= xorshift64_state;
- xorshift64_next;
- WR_ADDR <= getaddr(i < 256 ? i[7:4] : xorshift64_state[63:60]);
- xorshift64_next;
- RD_ADDR <= getaddr(i < 256 ? i[3:0] : xorshift64_state[59:56]);
- WR_EN <= xorshift64_state[55];
- xorshift64_next;
+ if (i == 0) begin
+ WR_EN <= 0;
+ RD_ADDR <= INIT_ADDR_0;
+ end else
+ if (i == 1) begin
+ WR_EN <= 0;
+ RD_ADDR <= INIT_ADDR_1;
+ end else
+ if (i == 2) begin
+ WR_EN <= 0;
+ RD_ADDR <= INIT_ADDR_2;
+ end else
+ if (i == 3) begin
+ WR_EN <= 0;
+ RD_ADDR <= INIT_ADDR_3;
+ end else begin
+ if (DBITS > 64)
+ WR_DATA <= (xorshift64_state << (DBITS-64)) ^ xorshift64_state;
+ else
+ WR_DATA <= xorshift64_state;
+ xorshift64_next;
+ WR_ADDR <= getaddr(i < 256 ? i[7:4] : xorshift64_state[63:60]);
+ xorshift64_next;
+ RD_ADDR <= getaddr(i < 256 ? i[3:0] : xorshift64_state[59:56]);
+ WR_EN <= xorshift64_state[55];
+ xorshift64_next;
+ end
#1; clk <= 1;
#1; clk <= 0;
set -ex
unisims=/opt/Xilinx/Vivado/2014.4/data/verilog/src/unisims
../../../yosys -v2 -l bram2.log -p synth_xilinx -o bram2_syn.v bram2.v
-iverilog -o bram2_tb bram2_tb.v bram2_syn.v -y $unisims $unisims/../glbl.v
+iverilog -T typ -o bram2_tb bram2_tb.v bram2_syn.v -y $unisims $unisims/../glbl.v
vvp -N bram2_tb
module myram(
input rd_clk,
input [ 7:0] rd_addr,
- output reg [15:0] rd_data,
+ output reg [17:0] rd_data,
input wr_clk,
input wr_enable,
input [ 7:0] wr_addr,
- input [15:0] wr_data
+ input [17:0] wr_data
);
- reg [15:0] memory [0:255];
+ reg [17:0] memory [0:255];
integer i;
+ function [17:0] hash(input [7:0] k);
+ reg [31:0] x;
+ begin
+ x = {k, ~k, k, ~k};
+ x = x ^ (x << 13);
+ x = x ^ (x >> 17);
+ x = x ^ (x << 5);
+ hash = x;
+ end
+ endfunction
+
initial begin
for (i = 0; i < 256; i = i+1)
- memory[i] = i;
+ memory[i] = hash(i);
end
always @(posedge rd_clk)
module testbench;
reg rd_clk;
reg [ 7:0] rd_addr;
- wire [15:0] rd_data;
+ wire [17:0] rd_data;
wire wr_clk = 0;
wire wr_enable = 0;
wire [ 7:0] wr_addr = 0;
- wire [15:0] wr_data = 0;
+ wire [17:0] wr_data = 0;
+
+ function [17:0] hash(input [7:0] k);
+ reg [31:0] x;
+ begin
+ x = {k, ~k, k, ~k};
+ x = x ^ (x << 13);
+ x = x ^ (x >> 17);
+ x = x ^ (x << 5);
+ hash = x;
+ end
+ endfunction
myram uut (
.rd_clk (rd_clk ),
rd_addr <= rd_addr + 1;
@(posedge rd_clk);
// $display("%3d %3d", i, rd_data);
- if (i != rd_data) begin
- $display("[%1t] ERROR: addr=%3d, data=%3d", $time, i, rd_data);
+ if (hash(i) !== rd_data) begin
+ $display("[%1t] ERROR: addr=%3d, data_mem=%18b, data_ref=%18b", $time, i, rd_data, hash(i));
$stop;
end
end