mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	iCE40 bram tests and fixes
This commit is contained in:
		
							parent
							
								
									d6f7698f59
								
							
						
					
					
						commit
						308a59aa18
					
				
					 6 changed files with 181 additions and 16 deletions
				
			
		|  | @ -20,23 +20,23 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); | |||
| 		case ({CLKPOL2, CLKPOL3}) | ||||
| 			2'b00: | ||||
| 				SB_RAM40_4KNRNW #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),               .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),              .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .MASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 				); | ||||
| 			2'b01: | ||||
| 				SB_RAM40_4KNR #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),               .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),              .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .MASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 				); | ||||
| 			2'b10: | ||||
| 				SB_RAM40_4KNW #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),               .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),              .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .MASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 				); | ||||
| 			2'b11: | ||||
| 				SB_RAM40_4K #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ ( | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),               .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 					.RDATA(A1DATA), .RADDR(A1ADDR_11),              .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1), | ||||
| 					.WDATA(B1DATA), .WADDR(B1ADDR_11), .MASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN) | ||||
| 				); | ||||
| 		endcase | ||||
| 	endgenerate | ||||
|  |  | |||
|  | @ -305,20 +305,43 @@ module SB_RAM40_4K ( | |||
| 	always @(posedge WCLK) begin | ||||
| 		if (WE && WCLKE) begin | ||||
| 			if (WRITE_MODE == 0) begin | ||||
| 				for (i=0; i<16; i=i+1) | ||||
| 					if (MASK[i]) memory[WADDR[7:0]][i] <= WDATA[i]; | ||||
| 				if (MASK[ 0]) memory[WADDR[7:0]][ 0] <= WDATA[ 0]; | ||||
| 				if (MASK[ 1]) memory[WADDR[7:0]][ 1] <= WDATA[ 1]; | ||||
| 				if (MASK[ 2]) memory[WADDR[7:0]][ 2] <= WDATA[ 2]; | ||||
| 				if (MASK[ 3]) memory[WADDR[7:0]][ 3] <= WDATA[ 3]; | ||||
| 				if (MASK[ 4]) memory[WADDR[7:0]][ 4] <= WDATA[ 4]; | ||||
| 				if (MASK[ 5]) memory[WADDR[7:0]][ 5] <= WDATA[ 5]; | ||||
| 				if (MASK[ 6]) memory[WADDR[7:0]][ 6] <= WDATA[ 6]; | ||||
| 				if (MASK[ 7]) memory[WADDR[7:0]][ 7] <= WDATA[ 7]; | ||||
| 				if (MASK[ 8]) memory[WADDR[7:0]][ 8] <= WDATA[ 8]; | ||||
| 				if (MASK[ 9]) memory[WADDR[7:0]][ 9] <= WDATA[ 9]; | ||||
| 				if (MASK[10]) memory[WADDR[7:0]][10] <= WDATA[10]; | ||||
| 				if (MASK[11]) memory[WADDR[7:0]][11] <= WDATA[11]; | ||||
| 				if (MASK[12]) memory[WADDR[7:0]][12] <= WDATA[12]; | ||||
| 				if (MASK[13]) memory[WADDR[7:0]][13] <= WDATA[13]; | ||||
| 				if (MASK[14]) memory[WADDR[7:0]][14] <= WDATA[14]; | ||||
| 				if (MASK[15]) memory[WADDR[7:0]][15] <= WDATA[15]; | ||||
| 				if (MASK[16]) memory[WADDR[7:0]][16] <= WDATA[16]; | ||||
| 			end | ||||
| 			if (WRITE_MODE == 1) begin | ||||
| 				for (i=0; i<2; i=i+1) | ||||
| 					if (WADDR[0] == i) memory[WADDR[8:1]][i*8 +: 8] <= WDATA[i][7:0]; | ||||
| 				if (WADDR[0] == 0) memory[WADDR[8:1]][0*8 +: 8] <= WDATA[7:0]; | ||||
| 				if (WADDR[0] == 1) memory[WADDR[8:1]][1*8 +: 8] <= WDATA[7:0]; | ||||
| 			end | ||||
| 			if (WRITE_MODE == 2) begin | ||||
| 				for (i=0; i<4; i=i+1) | ||||
| 					if (WADDR[1:0] == i) memory[WADDR[9:2]][i*4 +: 4] <= WDATA[i][3:0]; | ||||
| 				if (WADDR[1:0] == 0) memory[WADDR[9:2]][0*4 +: 4] <= WDATA[3:0]; | ||||
| 				if (WADDR[1:0] == 1) memory[WADDR[9:2]][1*4 +: 4] <= WDATA[3:0]; | ||||
| 				if (WADDR[1:0] == 2) memory[WADDR[9:2]][2*4 +: 4] <= WDATA[3:0]; | ||||
| 				if (WADDR[1:0] == 3) memory[WADDR[9:2]][3*4 +: 4] <= WDATA[3:0]; | ||||
| 			end | ||||
| 			if (WRITE_MODE == 3) begin | ||||
| 				for (i=0; i<8; i=i+1) | ||||
| 					if (WADDR[2:0] == i) memory[WADDR[10:3]][i*2 +: 2] <= WDATA[i][1:0]; | ||||
| 				if (WADDR[2:0] == 0) memory[WADDR[10:3]][0*2 +: 2] <= WDATA[1:0]; | ||||
| 				if (WADDR[2:0] == 1) memory[WADDR[10:3]][1*2 +: 2] <= WDATA[1:0]; | ||||
| 				if (WADDR[2:0] == 2) memory[WADDR[10:3]][2*2 +: 2] <= WDATA[1:0]; | ||||
| 				if (WADDR[2:0] == 3) memory[WADDR[10:3]][3*2 +: 2] <= WDATA[1:0]; | ||||
| 				if (WADDR[2:0] == 4) memory[WADDR[10:3]][4*2 +: 2] <= WDATA[1:0]; | ||||
| 				if (WADDR[2:0] == 5) memory[WADDR[10:3]][5*2 +: 2] <= WDATA[1:0]; | ||||
| 				if (WADDR[2:0] == 6) memory[WADDR[10:3]][6*2 +: 2] <= WDATA[1:0]; | ||||
| 				if (WADDR[2:0] == 7) memory[WADDR[10:3]][7*2 +: 2] <= WDATA[1:0]; | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
|  |  | |||
							
								
								
									
										1
									
								
								techlibs/ice40/tests/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								techlibs/ice40/tests/.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +1,2 @@ | |||
| test_ffs_[01][01][01][01][01]_* | ||||
| test_bram_[0-9]* | ||||
|  |  | |||
							
								
								
									
										17
									
								
								techlibs/ice40/tests/test_bram.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								techlibs/ice40/tests/test_bram.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| set -ex | ||||
| 
 | ||||
| for abits in 7 8 9 10 11 12; do | ||||
| for dbits in 2 4 8 16 24 32; do | ||||
| 	id="test_bram_${abits}_${dbits}" | ||||
| 	sed -e "s/ABITS = ./ABITS = $abits/g; s/DBITS = ./DBITS = $dbits/g;" < test_bram.v > ${id}.v | ||||
| 	sed -e "s/ABITS = ./ABITS = $abits/g; s/DBITS = ./DBITS = $dbits/g;" < test_bram_tb.v > ${id}_tb.v | ||||
| 	../../../yosys -ql ${id}_syn.log -p "synth_ice40" -o ${id}_syn.v ${id}.v | ||||
| 	iverilog -s bram_tb -o ${id}_tb ${id}_syn.v ${id}_tb.v /opt/lscc/iCEcube2.2014.08/verilog/sb_ice_syn.v | ||||
| 	# iverilog -s bram_tb -o ${id}_tb ${id}_syn.v ${id}_tb.v ../cells_sim.v | ||||
| 	./${id}_tb > ${id}_tb.txt | ||||
| 	if grep ERROR ${id}_tb.txt; then false; fi | ||||
| done; done | ||||
| echo OK | ||||
| 
 | ||||
							
								
								
									
										19
									
								
								techlibs/ice40/tests/test_bram.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								techlibs/ice40/tests/test_bram.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| module bram #( | ||||
| 	parameter ABITS = 8, DBITS = 8 | ||||
| ) ( | ||||
| 	input clk, | ||||
| 
 | ||||
| 	input [ABITS-1:0] WR_ADDR, | ||||
| 	input [DBITS-1:0] WR_DATA, | ||||
| 	input WR_EN, | ||||
| 
 | ||||
| 	input [ABITS-1:0] RD_ADDR, | ||||
| 	output reg [DBITS-1:0] RD_DATA | ||||
| ); | ||||
| 	reg [DBITS-1:0] memory [0:2**ABITS-1]; | ||||
| 
 | ||||
| 	always @(posedge clk) begin | ||||
| 		if (WR_EN) memory[WR_ADDR] <= WR_DATA; | ||||
| 		RD_DATA <= memory[RD_ADDR]; | ||||
| 	end | ||||
| endmodule | ||||
							
								
								
									
										105
									
								
								techlibs/ice40/tests/test_bram_tb.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								techlibs/ice40/tests/test_bram_tb.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | |||
| module bram_tb #( | ||||
| 	parameter ABITS = 8, DBITS = 8 | ||||
| ); | ||||
| 	reg clk; | ||||
| 	reg [ABITS-1:0] WR_ADDR; | ||||
| 	reg [DBITS-1:0] WR_DATA; | ||||
| 	reg WR_EN; | ||||
| 	reg [ABITS-1:0] RD_ADDR; | ||||
| 	wire [DBITS-1:0] RD_DATA; | ||||
| 
 | ||||
| 	bram uut  ( | ||||
| 		.clk    (clk    ), | ||||
| 		.WR_ADDR(WR_ADDR), | ||||
| 		.WR_DATA(WR_DATA), | ||||
| 		.WR_EN  (WR_EN  ), | ||||
| 		.RD_ADDR(RD_ADDR), | ||||
| 		.RD_DATA(RD_DATA) | ||||
| 	); | ||||
| 
 | ||||
| 	reg [63:0] xorshift64_state = 64'd88172645463325252 ^ (ABITS << 24) ^ (DBITS << 16); | ||||
| 
 | ||||
| 	task xorshift64_next; | ||||
| 		begin | ||||
| 		// see page 4 of Marsaglia, George (July 2003). "Xorshift RNGs". Journal of Statistical Software 8 (14). | ||||
| 		xorshift64_state = xorshift64_state ^ (xorshift64_state << 13); | ||||
| 		xorshift64_state = xorshift64_state ^ (xorshift64_state >>  7); | ||||
| 		xorshift64_state = xorshift64_state ^ (xorshift64_state << 17); | ||||
| 		end | ||||
| 	endtask | ||||
| 
 | ||||
| 	reg [ABITS-1:0] randaddr1; | ||||
| 	reg [ABITS-1:0] randaddr2; | ||||
| 	reg [ABITS-1:0] randaddr3; | ||||
| 
 | ||||
| 	function [31:0] getaddr(input [3:0] n); | ||||
| 		begin | ||||
| 			case (n) | ||||
| 				0: getaddr = 0; | ||||
| 				1: getaddr = 2**ABITS-1; | ||||
| 				2: getaddr = 'b101 << (ABITS / 3); | ||||
| 				3: getaddr = 'b101 << (2*ABITS / 3); | ||||
| 				4: getaddr = 'b11011 << (ABITS / 4); | ||||
| 				5: getaddr = 'b11011 << (2*ABITS / 4); | ||||
| 				6: getaddr = 'b11011 << (3*ABITS / 4); | ||||
| 				7: getaddr = randaddr1; | ||||
| 				8: getaddr = randaddr2; | ||||
| 				9: getaddr = randaddr3; | ||||
| 				default: begin | ||||
| 					getaddr = 1 << (2*n-16); | ||||
| 					if (!getaddr) getaddr = xorshift64_state; | ||||
| 				end | ||||
| 			endcase | ||||
| 		end | ||||
| 	endfunction | ||||
| 
 | ||||
| 	reg [DBITS-1:0] memory [0:2**ABITS-1]; | ||||
| 	reg [DBITS-1:0] expected_rd, expected_rd_masked; | ||||
| 
 | ||||
| 	event error; | ||||
| 	integer i, j; | ||||
| 
 | ||||
| 	initial begin | ||||
| 		// $dumpfile("testbench.vcd"); | ||||
| 		// $dumpvars(0, bram_tb); | ||||
| 
 | ||||
| 		xorshift64_next; | ||||
| 		xorshift64_next; | ||||
| 		xorshift64_next; | ||||
| 		xorshift64_next; | ||||
| 
 | ||||
| 		randaddr1 = xorshift64_state; | ||||
| 		xorshift64_next; | ||||
| 
 | ||||
| 		randaddr2 = xorshift64_state; | ||||
| 		xorshift64_next; | ||||
| 
 | ||||
| 		randaddr3 = xorshift64_state; | ||||
| 		xorshift64_next; | ||||
| 
 | ||||
| 		clk <= 0; | ||||
| 		for (i = 0; i < 512; i = i+1) begin | ||||
| 			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; | ||||
| 
 | ||||
| 			#1; clk <= 1; | ||||
| 			#1; clk <= 0; | ||||
| 
 | ||||
| 			expected_rd = memory[RD_ADDR]; | ||||
| 			if (WR_EN) memory[WR_ADDR] = WR_DATA; | ||||
| 
 | ||||
| 			for (j = 0; j < DBITS; j = j+1) | ||||
| 				expected_rd_masked[j] = expected_rd[j] !== 1'bx ? expected_rd[j] : RD_DATA[j]; | ||||
| 
 | ||||
| 			$display("#OUT# %3d | WA=%x WD=%x WE=%x | RA=%x RD=%x (%x) | %s", i, WR_ADDR, WR_DATA, WR_EN, RD_ADDR, RD_DATA, expected_rd, expected_rd_masked === RD_DATA ? "ok" : "ERROR"); | ||||
| 			if (expected_rd_masked !== RD_DATA) begin -> error; end | ||||
| 		end | ||||
| 	end | ||||
| endmodule | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue