aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/nexus/brams_map.v
blob: 214da4326c288140e5bab3e14fc8fc1225d0c091 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
module \$__NX_PDP16K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
	parameter CFG_ABITS = 9;
	parameter CFG_DBITS = 36;
	parameter CFG_ENABLE_A = 4;

	parameter CLKPOL2 = 1;
	parameter CLKPOL3 = 1;
	parameter [18431:0] INIT = 18432'b0;

	parameter _TECHMAP_BITS_CONNMAP_ = 8;
	parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK2_ = 0;
	parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK3_ = 0;

	input CLK2;
	input CLK3;

	input [CFG_ABITS-1:0] A1ADDR;
	input [CFG_DBITS-1:0] A1DATA;
	input [CFG_ENABLE_A-1:0] A1EN;

	input [CFG_ABITS-1:0] B1ADDR;
	output [CFG_DBITS-1:0] B1DATA;
	input B1EN;

	// Address is left justified, in x18 and above lower bits are byte enables
	localparam A_SHIFT =
		(CFG_DBITS == 36) ? 5 :
		(CFG_DBITS == 18) ? 4 :
		(CFG_DBITS == 9) ? 3 :
		(CFG_DBITS == 4) ? 2 :
		(CFG_DBITS == 2) ? 1 :
		0;

	// Different primitives needed for single vs dual clock case
	localparam SINGLE_CLOCK = (_TECHMAP_CONNMAP_CLK2_ == _TECHMAP_CONNMAP_CLK3_);

	localparam WIDTH = $sformatf("X%d", CFG_DBITS);

	wire [13:0] ra, wa;
	wire [35:0] rd, wd;

	assign ra = {B1ADDR, {A_SHIFT{1'b1}}};

	generate
		if (CFG_ENABLE_A > 1)
			assign wa = {A1ADDR, {(A_SHIFT-CFG_ENABLE_A){1'b1}}, A1EN};
		else
			assign wa = {A1ADDR, {A_SHIFT{1'b1}}};
	endgenerate

	assign wd = A1DATA;
	assign B1DATA = rd[CFG_DBITS-1:0];

	wire wck, rck;

	generate
		if (CLKPOL2)
			assign wck = CLK2;
		else
			INV wck_inv_i (.A(CLK2), .Z(wck));
		if (CLKPOL3)
			assign rck = CLK3;
		else
			INV wck_inv_i (.A(CLK3), .Z(rck));
	endgenerate

	wire we = |A1EN;

	localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 4) ? 256 : 288;

	function [319:0] permute_init;
		input [INIT_CHUNK_SIZE-1:0] chunk;
		integer i;
		begin
			if (CFG_DBITS <= 4) begin
				for (i = 0; i < 32; i = i + 1'b1)
					permute_init[i * 10 +: 10] = {2'b00, chunk[i * 8 +: 8]};
			end else begin
				for (i = 0; i < 32; i = i + 1'b1)
					permute_init[i * 10 +: 10] = {1'b0, chunk[i * 9 +: 9]};
			end
		end
	endfunction

	generate
		if (SINGLE_CLOCK) begin
			PDPSC16K #(
				.DATA_WIDTH_W(WIDTH),
				.DATA_WIDTH_R(WIDTH),
				.OUTREG("BYPASSED"),
				.ECC("DISABLED"),
				.GSR("DISABLED"),
`include "brams_init.vh"
			) _TECHMAP_REPLACE_ (
				.CLK(wck), .RST(1'b0),
				.DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111),
				.ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111)
			);
		end else begin
			PDP16K #(
				.DATA_WIDTH_W(WIDTH),
				.DATA_WIDTH_R(WIDTH),
				.OUTREG("BYPASSED"),
				.ECC("DISABLED"),
				.GSR("DISABLED"),
`include "brams_init.vh"
			) _TECHMAP_REPLACE_ (
				.CLKW(wck), .CLKR(rck), .RST(1'b0),
				.DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111),
				.ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111)
			);
		end
	endgenerate

endmodule