mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-24 13:18:56 +00:00
Add clock buffer insertion pass, improve iopadmap.
A few new attributes are defined for use in cell libraries: - iopad_external_pin: marks PAD cell's external-facing pin. Pad insertion will be skipped for ports that are already connected to such a pin. - clkbuf_sink: marks an input pin as a clock pin, requesting clock buffer insertion. - clkbuf_driver: marks an output pin as a clock buffer output pin. Clock buffer insertion will be skipped for nets that are already driven by such a pin. All three are module attributes that should be set to a comma-separeted list of pin names. Clock buffer insertion itself works as follows: 1. All cell ports, starting from bottom up, can be marked as clock sinks (requesting clock buffer insertion) or as clock buffer outputs. 2. If a wire in a given module is driven by a cell port that is a clock buffer output, it is in turn also considered a clock buffer output. 3. If an input port in a non-top module is connected to a clock sink in a contained cell, it is also in turn considered a clock sink. 4. If a wire in a module is driven by a non-clock-buffer cell, and is also connected to a clock sink port in a contained cell, a clock buffer is inserted in this module. 5. For the top module, a clock buffer is also inserted on input ports connected to clock sinks, optionally with a special kind of input PAD (such as IBUFG for Xilinx). 6. Clock buffer insertion on a given wire is skipped if the clkbuf_inhibit attribute is set on it.
This commit is contained in:
parent
78b30bbb11
commit
f4c62f33ac
10 changed files with 577 additions and 93 deletions
|
@ -42,10 +42,12 @@ module OBUF(output O, input I);
|
|||
assign O = I;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_driver = "O" *)
|
||||
module BUFG(output O, input I);
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_driver = "O" *)
|
||||
module BUFGCTRL(
|
||||
output O,
|
||||
input I0, input I1,
|
||||
|
@ -72,6 +74,7 @@ assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT);
|
|||
|
||||
endmodule
|
||||
|
||||
(* clkbuf_driver = "O" *)
|
||||
module BUFHCE(output O, input I, input CE);
|
||||
|
||||
parameter [0:0] INIT_OUT = 1'b0;
|
||||
|
@ -213,6 +216,7 @@ endmodule
|
|||
|
||||
`endif
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDRE (output reg Q, input C, CE, D, R);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
|
@ -225,6 +229,7 @@ module FDRE (output reg Q, input C, CE, D, R);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDSE (output reg Q, input C, CE, D, S);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
|
@ -237,6 +242,7 @@ module FDSE (output reg Q, input C, CE, D, S);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDCE (output reg Q, input C, CE, D, CLR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
|
@ -251,6 +257,7 @@ module FDCE (output reg Q, input C, CE, D, CLR);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDPE (output reg Q, input C, CE, D, PRE);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
|
@ -265,30 +272,35 @@ module FDPE (output reg Q, input C, CE, D, PRE);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDRE_1 (output reg Q, input C, CE, D, R);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDSE_1 (output reg Q, input C, CE, D, S);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDCE_1 (output reg Q, input C, CE, D, CLR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "C" *)
|
||||
module FDPE_1 (output reg Q, input C, CE, D, PRE);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "WCLK" *)
|
||||
(* abc_box_id = 5, abc_scc_break="D,WE" *)
|
||||
module RAM32X1D (
|
||||
output DPO, SPO,
|
||||
|
@ -307,6 +319,7 @@ module RAM32X1D (
|
|||
always @(posedge clk) if (WE) mem[a] <= D;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "WCLK" *)
|
||||
(* abc_box_id = 6, abc_scc_break="D,WE" *)
|
||||
module RAM64X1D (
|
||||
output DPO, SPO,
|
||||
|
@ -325,6 +338,7 @@ module RAM64X1D (
|
|||
always @(posedge clk) if (WE) mem[a] <= D;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "WCLK" *)
|
||||
(* abc_box_id = 7, abc_scc_break="D,WE" *)
|
||||
module RAM128X1D (
|
||||
output DPO, SPO,
|
||||
|
@ -340,6 +354,7 @@ module RAM128X1D (
|
|||
always @(posedge clk) if (WE) mem[A] <= D;
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "CLK" *)
|
||||
module SRL16E (
|
||||
output Q,
|
||||
input A0, A1, A2, A3, CE, CLK, D
|
||||
|
@ -358,6 +373,7 @@ module SRL16E (
|
|||
endgenerate
|
||||
endmodule
|
||||
|
||||
(* clkbuf_sink = "CLK" *)
|
||||
module SRLC32E (
|
||||
output Q,
|
||||
output Q31,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue