aboutsummaryrefslogtreecommitdiffstats
path: root/tests/arch/xilinx/asym_ram_sdp_write_wider.v
blob: cd61a3ccc751b422271a43562706e8a1510e58bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Asymmetric port RAM
// Write wider than Read. Write Statement in a loop.
// asym_ram_sdp_write_wider.v
module asym_ram_sdp_write_wider (clkA, clkB, weA, enaA, enaB, addrA, addrB, diA, doB);
	parameter WIDTHB = 4;
	parameter SIZEB = 1024;
	parameter ADDRWIDTHB = 10;

	parameter WIDTHA = 16;
	parameter SIZEA = 256;
	parameter ADDRWIDTHA = 8;

	input clkA;
	input clkB;
	input weA;
	input enaA, enaB;
	input [ADDRWIDTHA-1:0] addrA;
	input [ADDRWIDTHB-1:0] addrB;
	input [WIDTHA-1:0] diA;
	output [WIDTHB-1:0] doB;

	`define max(a,b) {(a) > (b) ? (a) : (b)}
	`define min(a,b) {(a) < (b) ? (a) : (b)}

	function integer log2;
	input integer value;
	reg [31:0] shifted;
	integer res;
	begin
		if (value < 2)
			log2 = value;
		else
		begin
			shifted = value-1;
			for (res=0; shifted>0; res=res+1)
				shifted = shifted>>1;
			log2 = res;
		end
	end
	endfunction

	localparam maxSIZE = `max(SIZEA, SIZEB);
	localparam maxWIDTH = `max(WIDTHA, WIDTHB);
	localparam minWIDTH = `min(WIDTHA, WIDTHB);

	localparam RATIO = maxWIDTH / minWIDTH;
	localparam log2RATIO = log2(RATIO);

	reg [minWIDTH-1:0] RAM [0:maxSIZE-1];
	reg [WIDTHB-1:0] readB;

	always @(posedge clkB) begin
		if (enaB) begin
			readB <= RAM[addrB];
		end
	end
	assign doB = readB;

	always @(posedge clkA)
	begin : ramwrite
		integer i;
		reg [log2RATIO-1:0] lsbaddr;
		for (i=0; i< RATIO; i= i+ 1) begin : write1
			lsbaddr = i;
			if (enaA) begin
				if (weA)
					RAM[{addrA, lsbaddr}] <= diA[(i+1)*minWIDTH-1 -: minWIDTH];
			end
		end
	end
endmodule