nexus: Add MULTADDSUB9X9WIDE sim model
[yosys.git] / techlibs / nexus / brams_map.v
1 module \$__NX_PDP16K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
2 parameter CFG_ABITS = 9;
3 parameter CFG_DBITS = 36;
4 parameter CFG_ENABLE_A = 4;
5
6 parameter CLKPOL2 = 1;
7 parameter CLKPOL3 = 1;
8 parameter [18431:0] INIT = 18432'b0;
9
10 parameter _TECHMAP_BITS_CONNMAP_ = 8;
11 parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK2_ = 0;
12 parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_CLK3_ = 0;
13
14 input CLK2;
15 input CLK3;
16
17 input [CFG_ABITS-1:0] A1ADDR;
18 input [CFG_DBITS-1:0] A1DATA;
19 input [CFG_ENABLE_A-1:0] A1EN;
20
21 input [CFG_ABITS-1:0] B1ADDR;
22 output [CFG_DBITS-1:0] B1DATA;
23 input B1EN;
24
25 // Address is left justified, in x18 and above lower bits are byte enables
26 localparam A_SHIFT =
27 (CFG_DBITS == 36) ? 5 :
28 (CFG_DBITS == 18) ? 4 :
29 (CFG_DBITS == 9) ? 3 :
30 (CFG_DBITS == 4) ? 2 :
31 (CFG_DBITS == 2) ? 1 :
32 0;
33
34 // Different primitives needed for single vs dual clock case
35 localparam SINGLE_CLOCK = (_TECHMAP_CONNMAP_CLK2_ == _TECHMAP_CONNMAP_CLK3_);
36
37 localparam WIDTH = $sformatf("X%d", CFG_DBITS);
38
39 wire [13:0] ra, wa;
40 wire [35:0] rd, wd;
41
42 assign ra = {B1ADDR, {A_SHIFT{1'b1}}};
43
44 generate
45 if (CFG_ENABLE_A > 1)
46 assign wa = {A1ADDR, {(A_SHIFT-CFG_ENABLE_A){1'b1}}, A1EN};
47 else
48 assign wa = {A1ADDR, {A_SHIFT{1'b1}}};
49 endgenerate
50
51 assign wd = A1DATA;
52 assign B1DATA = rd[CFG_DBITS-1:0];
53
54 wire wck, rck;
55
56 generate
57 if (CLKPOL2)
58 assign wck = CLK2;
59 else
60 INV wck_inv_i (.A(CLK2), .Z(wck));
61 if (CLKPOL3)
62 assign rck = CLK3;
63 else
64 INV wck_inv_i (.A(CLK3), .Z(rck));
65 endgenerate
66
67 wire we = |A1EN;
68
69 localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 4) ? 256 : 288;
70
71 function [319:0] permute_init;
72 input [INIT_CHUNK_SIZE-1:0] chunk;
73 integer i;
74 begin
75 if (CFG_DBITS <= 4) begin
76 for (i = 0; i < 32; i = i + 1'b1)
77 permute_init[i * 10 +: 10] = {2'b00, chunk[i * 8 +: 8]};
78 end else begin
79 for (i = 0; i < 32; i = i + 1'b1)
80 permute_init[i * 10 +: 10] = {1'b0, chunk[i * 9 +: 9]};
81 end
82 end
83 endfunction
84
85 generate
86 if (SINGLE_CLOCK) begin
87 PDPSC16K #(
88 .DATA_WIDTH_W(WIDTH),
89 .DATA_WIDTH_R(WIDTH),
90 .OUTREG("BYPASSED"),
91 .ECC("DISABLED"),
92 .GSR("DISABLED"),
93 `include "brams_init.vh"
94 ) _TECHMAP_REPLACE_ (
95 .CLK(wck), .RST(1'b0),
96 .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111),
97 .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111)
98 );
99 end else begin
100 PDP16K #(
101 .DATA_WIDTH_W(WIDTH),
102 .DATA_WIDTH_R(WIDTH),
103 .OUTREG("BYPASSED"),
104 .ECC("DISABLED"),
105 .GSR("DISABLED"),
106 `include "brams_init.vh"
107 ) _TECHMAP_REPLACE_ (
108 .CLKW(wck), .CLKR(rck), .RST(1'b0),
109 .DI(wd), .ADW(wa), .CEW(we), .CSW(3'b111),
110 .ADR(ra), .DO(rd), .CER(B1EN), .CSR(3'b111)
111 );
112 end
113 endgenerate
114
115 endmodule