From e051d7d51614c72e0a2d21a2af6c4d81dbc045f1 Mon Sep 17 00:00:00 2001 From: Andreas Olofsson Date: Mon, 22 Feb 2016 23:47:27 -0500 Subject: [PATCH] Adding vectorized iddr/oddr cells --- common/hdl/oh_iddr.v | 64 ++++++++++++++++++++++++++++++++++++++++++++ common/hdl/oh_oddr.v | 43 +++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 common/hdl/oh_iddr.v create mode 100644 common/hdl/oh_oddr.v diff --git a/common/hdl/oh_iddr.v b/common/hdl/oh_iddr.v new file mode 100644 index 0000000..8d130e8 --- /dev/null +++ b/common/hdl/oh_iddr.v @@ -0,0 +1,64 @@ +module oh_iddr (/*AUTOARG*/ + // Outputs + q1, q2, + // Inputs + clk, ce, din + ); + + //######################################################### + //# INTERFACE + //######################################################### + + //parameters + parameter DW = 32; + parameter DDR_CLK_EDGE = ""; //"OPPOSITE EDGE", "SAME EDGE", "SAME EDGE PIPELINE" + localparam HOLDHACK = 0.1; + + input clk; // clock + input ce; // clock enable, set to high to clock in data + input [DW-1:0] din; // data input + + output [DW-1:0] q1; // iddr registered output (first) + output [DW-1:0] q2; // iddr registered output (second) + + //######################################################### + //# BODY + //######################################################### + + //trick for string comparison? + localparam [152:1] DDR_CLK_EDGE_REG = DDR_CLK_EDGE; + + reg [DW-1:0] q1_pos; + reg [DW-1:0] q1_reg; + + reg [DW-1:0] q2_pos; + reg [DW-1:0] q2_neg; + + always @ (posedge clk) + if(ce) + q1_pos[DW-1:0] <= #(HOLDHACK) din[DW-1:0]; + + always @ (posedge clk) + if(ce) + q1_reg[DW-1:0] <= #(HOLDHACK) q1_pos[DW-1:0]; + + always @ (negedge clk) + if(ce) + q2_neg[DW-1:0] <= #(HOLDHACK) din[DW-1:0]; + + always @ (posedge clk) + if(ce) + q2_pos[DW-1:0] <= #(HOLDHACK) q2_neg[DW-1:0]; + + //Select behavior based on parameters + assign q1[DW-1:0] = (DDR_CLK_EDGE_REG == "SAME_EDGE_PIPELINED") ? q1_reg[DW-1:0] : + (DDR_CLK_EDGE_REG == "SAME_EDGE") ? q1_pos[DW-1:0] : + 'b0; + + assign q2[DW-1:0] = (DDR_CLK_EDGE_REG == "SAME_EDGE_PIPELINED") ? q2_pos[DW-1:0] : + (DDR_CLK_EDGE_REG == "SAME_EDGE") ? q2_pos[DW-1:0] : + 'b0; + +endmodule // oh_iddr + + diff --git a/common/hdl/oh_oddr.v b/common/hdl/oh_oddr.v new file mode 100644 index 0000000..eb7a19a --- /dev/null +++ b/common/hdl/oh_oddr.v @@ -0,0 +1,43 @@ +module oh_oddr (/*AUTOARG*/ + // Outputs + out, + // Inputs + clk, ce, din1, din2 + ); + //######################################################### + //# INTERFACE + //######################################################### + + //parameters + parameter DW = 32; + + //signals + input clk; // clock input + input ce; // clock enable input + input [DW-1:0] din1; // data input1 + input [DW-1:0] din2; // data input2 + output [DW-1:0] out; // ddr output + + //######################################################### + //# BODY + //######################################################### + + reg [DW-1:0] q1; + reg [DW-1:0] q2; + reg [DW-1:0] q2_reg; + + //Generate different logic based on parameters + always @ (posedge clk) + q1[DW-1:0] <= din1[DW-1:0]; + + always @ (posedge clk) + q2[DW-1:0] <= din2[DW-1:0]; + + always @ (negedge clk) + q2_reg[DW-1:0] <= q2[DW-1:0]; + + assign q = clk ? q1[DW-1:0] : q2_reg[DW-1:0]; + +endmodule // oh_oddr + +