You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
5.1 KiB
Coq

// © IBM Corp. 2021
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by the terms below; you may not use the files in this
// repository except in compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the License, the "Work" hereby includes implementations of
// the work of authorship in physical form.
//
// Unless required by applicable law or agreed to in writing, the reference design distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
// governing permissions and limitations under the License.
//
// Brief explanation of modifications:
//
// Modification 1: This modification extends the patent license to an implementation of the Work in physical form i.e.,
// it unambiguously permits a user to make and use the physical chip.
// Local Clock Buffer for arrays
// Generates sim or implementation logic, depending on GENMODE.
`timescale 1 ns / 1 ns
/*
Config_LCB
31 enable delay
30 sdr=0 ddr=1
28:29 tap1 sel (pulse width)
26:27 tap2 sel (pulse 2 separation gross)
24:25 tap3 sel (pulse 2 separation fine)
*/
module ra_lcb #(
parameter GENMODE = 0
) (
input clk,
input reset,
input [0:31] cfg,
output strobe
);
reg no_delay_q;
reg no_delay_b_q;
reg ddr_q;
reg [0:3] tap1_sel_q;
reg [0:2] tap2_sel_q;
reg [0:3] tap3_sel_q;
wire [0:3] delay1;
wire [0:3] tap1;
wire tap1_b;
wire pulse1_b;
wire delay2_b;
wire [0:15] delay2;
wire [0:2] tap2;
wire tap2_b;
wire [0:3] delay3;
wire [0:3] tap3;
wire pulse2_b;
wire pulse;
// predecode and keep locally
//wtf make these dff cells?
always @(posedge clk) begin
no_delay_q <= ~cfg[31];
no_delay_b_q <= cfg[31];
ddr_q <= cfg[30];
tap1_sel_q[0] <= cfg[28:29] == 2'b00;
tap1_sel_q[1] <= cfg[28:29] == 2'b01;
tap1_sel_q[2] <= cfg[28:29] == 2'b10;
tap1_sel_q[3] <= cfg[28:29] == 2'b11;
tap2_sel_q[0] <= cfg[26:27] == 2'b00;
tap2_sel_q[1] <= cfg[26:27] == 2'b01;
tap2_sel_q[2] <= cfg[26:27] == 2'b10;
//tap2_sel_q[3] <= cfg[26:27] == 2'b11;
tap3_sel_q[0] <= cfg[24:25] == 2'b00;
tap3_sel_q[1] <= cfg[24:25] == 2'b01;
tap3_sel_q[2] <= cfg[24:25] == 2'b10;
tap3_sel_q[3] <= cfg[24:25] == 2'b11;
end
// generate strobe
// array needs strobe to precharge the bitlines before evaluate phase
// strobe is AND'd with enable/addr to create precharge signal -> strobe=0 == precharge
// sdr: one strobe per clk
// ddr: two strobes per clk; early/late select for addr sel/data out latch
generate
if (GENMODE == 0)
assign strobe = ~clk;
else begin
genvar i;
// dly1 - create pulse 1 (and 2 if ddr) width
sky130_fd_sc_hd__buf_1 dly1_0(.A(clk), .X(delay1[0]));
//wtf need to size properly; could spread into 1/2/4/7 etc.
// there are buf_[1,2,4,6,8,12,16]
// bufbuf_[8,16]
// clkbuf_[1,2,4,8,16]
// clkdlybufs15_[1,2]
// clkdlybufs18_[1,2]
// clkdlybufs25_[1,2]
// blkdlybufs50_[1,2]
for (i = 1; i < 4; i = i + 1) begin
sky130_fd_sc_hd__buf_1 dly1_n(.A(delay1[i-1]), .X(delay1[i]));
end
for (i = 0; i < 4; i = i + 1) begin
sky130_fd_sc_hd__and2_1 dly1_sel(.A(tap1_sel_q[i]), .B(delay1[i]), .X(tap1[i]));
end
sky130_fd_sc_hd__nor4_1 dly1_or(.A(tap1[0]), .B(tap1[1]), .C(tap1[2]), .D(tap1[3]), .X(tap1_b));
sky130_fd_sc_hd__nand2_1 dly1_out(.A(clk), .B(tap1_b), .Y(pulse1_b));
// dly2 - create pulse 2 separation (disable for sdr)
sky130_fd_sc_hd__and2_1 dly2_in(.A(ddr_q), .B(pulse1_b), .X(delay2_b));
sky130_fd_sc_hd__inv_1 dly2_0(.A(delay2_b), .Y(delay2[0]));
// 2-stage
// +8/12/16
// +0/1/2/3
for (i = 1; i < 16; i = i + 1) begin
sky130_fd_sc_hd__inv_1 dly2_n(.A(delay2[i-1]), .Y(delay2[i]));
end
sky130_fd_sc_hd__and2_1 dly2_sel0(.A(tap2_sel_q[0]), .B(delay2[7]), .X(tap2[0]));
sky130_fd_sc_hd__and2_1 dly2_sel1(.A(tap2_sel_q[1]), .B(delay2[11]), .X(tap2[1]));
sky130_fd_sc_hd__and2_1 dly2_sel2(.A(tap2_sel_q[2]), .B(delay2[15]), .X(tap2[2]));
sky130_fd_sc_hd__or3_1 dly3_0(.A(tap2[0]), .B(tap2[1]), .C(tap2[2]), .X(delay3[0]));
for (i = 1; i < 4; i = i + 1) begin
sky130_fd_sc_hd__buf_1 dly3_n (.A(delay3[i-1]), .X(delay3[i]));
end
for (i = 0; i < 4; i = i + 1) begin
sky130_fd_sc_hd__and2_1 dly3_sel(.A(tap3_sel_q[i]), .B(delay3[i]), .X(tap3[i]));
end
sky130_fd_sc_hd__nor4_1 dly3_out(.A(tap3[0]), .B(tap3[1]), .C(tap3[2]), .D(tap3[3]), .X(pulse2_b));
// combine
sky130_fd_sc_hd__nand2_1 pulse12(.A(pulse1_b), .B(pulse2_b), .Y(pulse));
// select and invert (neg-active precharge)
sky130_fd_sc_hd__a22oi_1 strobe_out(.A1(no_delay_q), .A2(clk), .B1(no_delay_b_q), .B2(pulse), .X(strobe));
end
endgenerate
endmodule