Tests for ram_style = "huge"

iCE40 SPRAM and Xilinx URAM
This commit is contained in:
KrystalDelusion 2022-07-07 10:27:54 +12:00
parent de2f140c09
commit af1b9c9e07
4 changed files with 219 additions and 0 deletions

22
tests/arch/ice40/spram.v Normal file
View File

@ -0,0 +1,22 @@
module top (clk, write_enable, read_enable, write_data, addr, read_data);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
parameter SKIP_RDEN = 1;
input clk;
input write_enable, read_enable;
input [DATA_WIDTH - 1 : 0] write_data;
input [ADDR_WIDTH - 1 : 0] addr;
output [DATA_WIDTH - 1 : 0] read_data;
(* ram_style = "huge" *)
reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0];
always @(posedge clk) begin
if (write_enable)
mem[addr] <= write_data;
else if (SKIP_RDEN || read_enable)
read_data <= mem[addr];
end
endmodule

15
tests/arch/ice40/spram.ys Normal file
View File

@ -0,0 +1,15 @@
read_verilog spram.v
hierarchy -top top
synth_ice40
select -assert-count 1 t:SB_SPRAM256KA
select -assert-none t:SB_SPRAM256KA %% t:* %D
# Testing with pattern as described in pattern document
design -reset
read_verilog spram.v
chparam -set SKIP_RDEN 0
hierarchy -top top
synth_ice40
select -assert-count 1 t:SB_SPRAM256KA
# Below fails due to extra SB_LUT4
# select -assert-none t:SB_SPRAM256KA %% t:* %D

View File

@ -0,0 +1,122 @@
module priority_memory (
clk, wren_a, rden_a, addr_a, wdata_a, rdata_a,
wren_b, rden_b, addr_b, wdata_b, rdata_b
);
parameter ABITS = 12;
parameter WIDTH = 72;
input clk;
input wren_a, rden_a, wren_b, rden_b;
input [ABITS-1:0] addr_a, addr_b;
input [WIDTH-1:0] wdata_a, wdata_b;
output reg [WIDTH-1:0] rdata_a, rdata_b;
`ifdef USE_HUGE
(* ram_style = "huge" *)
`endif
reg [WIDTH-1:0] mem [0:2**ABITS-1];
integer i;
initial begin
rdata_a <= 'h0;
rdata_b <= 'h0;
end
`ifndef FLIP_PORTS
always @(posedge clk) begin
// A port
if (wren_a)
mem[addr_a] <= wdata_a;
else if (rden_a)
rdata_a <= mem[addr_a];
// B port
if (wren_b)
mem[addr_b] <= wdata_b;
else if (rden_b)
if (wren_a && addr_a == addr_b)
rdata_b <= wdata_a;
else
rdata_b <= mem[addr_b];
end
`else // FLIP PORTS
always @(posedge clk) begin
// A port
if (wren_b)
mem[addr_b] <= wdata_b;
else if (rden_b)
rdata_b <= mem[addr_b];
// B port
if (wren_a)
mem[addr_a] <= wdata_a;
else if (rden_a)
if (wren_b && addr_a == addr_b)
rdata_a <= wdata_b;
else
rdata_a <= mem[addr_a];
end
`endif
endmodule
module sp_write_first (clk, wren_a, rden_a, addr_a, wdata_a, rdata_a);
parameter ABITS = 12;
parameter WIDTH = 72;
input clk;
input wren_a, rden_a;
input [ABITS-1:0] addr_a;
input [WIDTH-1:0] wdata_a;
output reg [WIDTH-1:0] rdata_a;
(* ram_style = "huge" *)
reg [WIDTH-1:0] mem [0:2**ABITS-1];
integer i;
initial begin
rdata_a <= 'h0;
end
always @(posedge clk) begin
// A port
if (wren_a)
mem[addr_a] <= wdata_a;
if (rden_a)
if (wren_a)
rdata_a <= wdata_a;
else
rdata_a <= mem[addr_a];
end
endmodule
module sp_read_first (clk, wren_a, rden_a, addr_a, wdata_a, rdata_a);
parameter ABITS = 12;
parameter WIDTH = 72;
input clk;
input wren_a, rden_a;
input [ABITS-1:0] addr_a;
input [WIDTH-1:0] wdata_a;
output reg [WIDTH-1:0] rdata_a;
(* ram_style = "huge" *)
reg [WIDTH-1:0] mem [0:2**ABITS-1];
integer i;
initial begin
rdata_a <= 'h0;
end
always @(posedge clk) begin
// A port
if (wren_a)
mem[addr_a] <= wdata_a;
if (rden_a)
rdata_a <= mem[addr_a];
end
endmodule

View File

@ -0,0 +1,60 @@
# no uram by default
design -reset
read_verilog priority_memory.v
synth_xilinx -family xcup -top priority_memory
select -assert-none t:URAM288
# uram parameter
design -reset
read -define USE_HUGE
read_verilog priority_memory.v
synth_xilinx -family xcup -top priority_memory -noiopad
select -assert-count 1 t:URAM288
# uram option
design -reset
read_verilog priority_memory.v
synth_xilinx -family xcup -top priority_memory -noiopad -uram
# check for URAM block
select -assert-count 1 t:URAM288
# check port A in code maps to port A in hardware:
# %co:+[DOUT_A] selects everything connected to a URAM288.DOUT_A port
# w:rdata_a selects the wire rdata_a
# %i finds the intersection of the two above selections
# if the result is 1 then the wire rdata_a is connected to Port A correctly
select -assert-count 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i
# we expect no more than 2 LUT2s to control the hardware priority
# if there are extra LUTs, then it is likely emulating logic it shouldn't
# ignore anything using blif, since that doesn't seem to support priority logic
# and is indicative of using verific/tabby
select -assert-max 2 t:LUT* n:*blif* %d
# reverse priority
design -reset
read -define FLIP_PORTS
read_verilog priority_memory.v
synth_xilinx -family xcup -top priority_memory -noiopad -uram
# test priority is mapped correctly, rdata_a should now be connected to Port B
# see above for details
select -assert-count 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i
# sp write first
design -reset
read_verilog priority_memory.v
synth_xilinx -family xcup -top sp_write_first -noiopad
select -assert-count 1 t:URAM288
# write first connects rdata_a to port B
# similar to above, but also tests that rdata_a *isn't* connected to port A
select -assert-none 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i
select -assert-count 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i
# sp read first
design -reset
read_verilog priority_memory.v
synth_xilinx -family xcup -top sp_read_first -noiopad
select -assert-count 1 t:URAM288
# read first connects rdata_a to port A
# see above for details
select -assert-count 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i
select -assert-none 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i