Manar | 68e0363 | 2020-11-09 13:25:13 +0200 | [diff] [blame] | 1 | /* |
| 2 | Building blocks for DFF based RAM compiler for SKY130 |
| 3 | WORD : 32-bit memory word with select and byte-level WE |
| 4 | DEC6x64 : 6x64 Binary decoder |
| 5 | SRAM64x32 : Tri-state based 64x32 DFF RAM |
| 6 | */ |
| 7 | |
| 8 | module BYTE ( |
| 9 | input CLK, |
| 10 | input WE, |
| 11 | input SEL, |
| 12 | input [7:0] Di, |
| 13 | output [7:0] Do, |
| 14 | input VPWR, |
| 15 | input VGND |
| 16 | ); |
| 17 | |
| 18 | wire [7:0] q_wire; |
| 19 | wire we_wire; |
| 20 | wire SEL_B; |
| 21 | wire GCLK; |
| 22 | |
| 23 | sky130_fd_sc_hd__inv_1 INV( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .Y(SEL_B), .A(SEL)); |
| 24 | sky130_fd_sc_hd__and2_1 CGAND( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .A(SEL), .B(WE), .X(we_wire) ); |
| 25 | sky130_fd_sc_hd__dlclkp_1 CG( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .CLK(CLK), .GCLK(GCLK), .GATE(we_wire) ); |
| 26 | |
| 27 | generate |
| 28 | genvar i; |
| 29 | for(i=0; i<8; i=i+1) begin : BIT |
| 30 | sky130_fd_sc_hd__dfxtp_1 FF ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .D(Di[i]), .Q(q_wire[i]), .CLK(GCLK) ); |
| 31 | sky130_fd_sc_hd__ebufn_2 OBUF ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .A(q_wire[i]), .Z(Do[i]), .TE_B(SEL_B) ); |
| 32 | end |
| 33 | endgenerate |
| 34 | |
| 35 | endmodule |
| 36 | |
| 37 | |
| 38 | module WORD32 ( |
| 39 | input CLK, |
| 40 | input [3:0] WE, |
| 41 | input SEL, |
| 42 | input [31:0] Di, |
| 43 | output [31:0] Do, |
| 44 | input VPWR, |
| 45 | input VGND |
| 46 | ); |
| 47 | |
| 48 | BYTE B0 ( .VPWR(VPWR), .VGND(VGND), .CLK(CLK), .WE(WE[0]), .SEL(SEL), .Di(Di[7:0]), .Do(Do[7:0]) ); |
| 49 | BYTE B1 ( .VPWR(VPWR), .VGND(VGND), .CLK(CLK), .WE(WE[1]), .SEL(SEL), .Di(Di[15:8]), .Do(Do[15:8]) ); |
| 50 | BYTE B2 ( .VPWR(VPWR), .VGND(VGND), .CLK(CLK), .WE(WE[2]), .SEL(SEL), .Di(Di[23:16]), .Do(Do[23:16]) ); |
| 51 | BYTE B3 ( .VPWR(VPWR), .VGND(VGND), .CLK(CLK), .WE(WE[3]), .SEL(SEL), .Di(Di[31:24]), .Do(Do[31:24]) ); |
| 52 | |
| 53 | endmodule |
| 54 | |
| 55 | module DEC2x4 ( |
| 56 | input EN, |
| 57 | input [1:0] A, |
| 58 | output [3:0] SEL, |
| 59 | input VPWR, |
| 60 | input VGND |
| 61 | ); |
| 62 | sky130_fd_sc_hd__nor3b_2 AND0 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .Y(SEL[0]), .A(A[0]), .B(A[1]), .C_N(EN) ); |
| 63 | sky130_fd_sc_hd__and3b_2 AND1 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[1]), .A_N(A[1]), .B(A[0]), .C(EN) ); |
| 64 | sky130_fd_sc_hd__and3b_2 AND2 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[2]), .A_N(A[0]), .B(A[1]), .C(EN) ); |
| 65 | sky130_fd_sc_hd__and3_2 AND3 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[3]), .A(A[1]), .B(A[0]), .C(EN) ); |
| 66 | |
| 67 | endmodule |
| 68 | |
| 69 | module DEC3x8 ( |
| 70 | input EN, |
| 71 | input [2:0] A, |
| 72 | output [7:0] SEL, |
| 73 | input VPWR, |
| 74 | input VGND |
| 75 | ); |
| 76 | sky130_fd_sc_hd__nor4b_2 AND0 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .Y(SEL[0]) , .A(A[0]), .B(A[1]) , .C(A[2]), .D_N(EN) ); // 000 |
| 77 | sky130_fd_sc_hd__and4bb_2 AND1 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[1]) , .A_N(A[2]), .B_N(A[1]), .C(A[0]) , .D(EN) ); // 001 |
| 78 | sky130_fd_sc_hd__and4bb_2 AND2 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[2]) , .A_N(A[2]), .B_N(A[0]), .C(A[1]) , .D(EN) ); // 010 |
| 79 | sky130_fd_sc_hd__and4b_2 AND3 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[3]) , .A_N(A[2]), .B(A[1]), .C(A[0]) , .D(EN) ); // 011 |
| 80 | sky130_fd_sc_hd__and4bb_2 AND4 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[4]) , .A_N(A[0]), .B_N(A[1]), .C(A[2]) , .D(EN) ); // 100 |
| 81 | sky130_fd_sc_hd__and4b_2 AND5 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[5]) , .A_N(A[1]), .B(A[0]), .C(A[2]) , .D(EN) ); // 101 |
| 82 | sky130_fd_sc_hd__and4b_2 AND6 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[6]) , .A_N(A[0]), .B(A[1]), .C(A[2]) , .D(EN) ); // 110 |
| 83 | sky130_fd_sc_hd__and4_2 AND7 ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(SEL[7]) , .A(A[0]), .B(A[1]), .C(A[2]) , .D(EN) ); // 111 |
| 84 | endmodule |
| 85 | |
| 86 | |
| 87 | module DEC6x64 ( |
| 88 | input EN, |
| 89 | input [5:0] A, |
| 90 | output [63:0] SEL, |
| 91 | input VPWR, |
| 92 | input VGND |
| 93 | ); |
| 94 | wire [7:0] SEL0_w ; |
| 95 | DEC3x8 DEC_L0 ( .VPWR(VPWR), .VGND(VGND), .EN(EN), .A(A[5:3]), .SEL(SEL0_w) ); |
| 96 | |
| 97 | generate |
| 98 | genvar i; |
| 99 | for(i=0; i<8; i=i+1) begin : DEC_L1 |
| 100 | DEC3x8 U ( .VPWR(VPWR), .VGND(VGND), .EN(SEL0_w[i]), .A(A[2:0]), .SEL(SEL[7+8*i: 8*i]) ); |
| 101 | end |
| 102 | endgenerate |
| 103 | endmodule |
| 104 | |
| 105 | module MUX4x1_32( |
| 106 | input [31:0] A0, A1, A2, A3, |
| 107 | input [1:0] S, |
| 108 | output [31:0] X, |
| 109 | input VPWR, |
| 110 | input VGND |
| 111 | ); |
| 112 | sky130_fd_sc_hd__mux4_1 MUX[31:0] ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .A0(A0), .A1(A1), .A2(A2), .A3(A3), .S0(S[0]), .S1(S[1]), .X(X) ); |
| 113 | endmodule |
| 114 | |
| 115 | module SRAM64x32( |
| 116 | input CLK, |
| 117 | input [3:0] WE, |
| 118 | input EN, |
| 119 | input [31:0] Di, |
| 120 | output [31:0] Do, |
| 121 | input [5:0] A, |
| 122 | input VPWR, |
| 123 | input VGND |
| 124 | ); |
| 125 | |
| 126 | wire [63:0] SEL; |
| 127 | wire [31:0] Do_pre; |
| 128 | wire [31:0] Di_buf; |
| 129 | wire CLK_buf; |
| 130 | wire [3:0] WE_buf; |
| 131 | |
| 132 | sky130_fd_sc_hd__clkbuf_16 CLKBUF ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(CLK_buf), .A(CLK)); |
| 133 | sky130_fd_sc_hd__clkbuf_16 WEBUF[3:0] ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(WE_buf), .A(WE)); |
| 134 | sky130_fd_sc_hd__clkbuf_16 DIBUF[31:0] ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .X(Di_buf), .A(Di)); |
| 135 | |
| 136 | DEC6x64 DEC ( .VPWR(VPWR), .VGND(VGND), .EN(EN), .A(A), .SEL(SEL) ); |
| 137 | |
| 138 | generate |
| 139 | genvar i; |
| 140 | for (i=0; i< 64; i=i+1) begin : WORD |
| 141 | WORD32 W ( .VPWR(VPWR), .VGND(VGND), .CLK(CLK_buf), .WE(WE_buf), .SEL(SEL[i]), .Di(Di_buf), .Do(Do_pre) ); |
| 142 | end |
| 143 | endgenerate |
| 144 | |
| 145 | // Ensure that the Do_pre lines are not floating when EN = 0 |
| 146 | sky130_fd_sc_hd__ebufn_4 FLOATBUF[31:0] ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .A({32{EN}}), .Z(Do_pre), .TE_B({32{EN}}) ); |
| 147 | |
| 148 | generate |
| 149 | //genvar i; |
| 150 | for(i=0; i<32; i=i+1) begin : OUT |
| 151 | sky130_fd_sc_hd__dfxtp_1 FF ( .VPWR(VPWR), .VGND(VGND), .VPB(VPWR), .VNB(VGND), .D(Do_pre[i]), .Q(Do[i]), .CLK(CLK) ); |
| 152 | end |
| 153 | endgenerate |
| 154 | |
| 155 | endmodule |
| 156 | |