2021-09-13 10:16:15 -05:00
|
|
|
/*
|
|
|
|
* yosys -- Yosys Open SYnthesis Suite
|
|
|
|
*
|
|
|
|
* Copyright (C) 2021 Cologne Chip AG <support@colognechip.com>
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
`timescale 1ps/1ps
|
|
|
|
|
|
|
|
module CC_IBUF #(
|
|
|
|
parameter PIN_NAME = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter [0:0] PULLUP = 1'bx,
|
|
|
|
parameter [0:0] PULLDOWN = 1'bx,
|
|
|
|
parameter [0:0] KEEPER = 1'bx,
|
|
|
|
parameter [0:0] SCHMITT_TRIGGER = 1'bx,
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_IBF = 1'bx,
|
|
|
|
parameter [0:0] FF_IBF = 1'bx
|
|
|
|
)(
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
input I,
|
|
|
|
output Y
|
|
|
|
);
|
|
|
|
assign Y = I;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(I => Y) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_OBUF #(
|
|
|
|
parameter PIN_NAME = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter DRIVE = "UNDEFINED",
|
|
|
|
parameter SLEW = "UNDEFINED",
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_OBF = 1'bx,
|
|
|
|
parameter [0:0] FF_OBF = 1'bx
|
|
|
|
)(
|
|
|
|
input A,
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
output O
|
|
|
|
);
|
|
|
|
assign O = A;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(A => O) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_TOBUF #(
|
|
|
|
parameter PIN_NAME = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter DRIVE = "UNDEFINED",
|
|
|
|
parameter SLEW = "UNDEFINED",
|
|
|
|
parameter [0:0] PULLUP = 1'bx,
|
|
|
|
parameter [0:0] PULLDOWN = 1'bx,
|
|
|
|
parameter [0:0] KEEPER = 1'bx,
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_OBF = 1'bx,
|
|
|
|
parameter [0:0] FF_OBF = 1'bx
|
|
|
|
)(
|
|
|
|
input A, T,
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
output O
|
|
|
|
);
|
|
|
|
assign O = T ? 1'bz : A;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(A => O) = (0:0:0, 0:0:0);
|
|
|
|
(T => O) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_IOBUF #(
|
|
|
|
parameter PIN_NAME = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter DRIVE = "UNDEFINED",
|
|
|
|
parameter SLEW = "UNDEFINED",
|
|
|
|
parameter [0:0] PULLUP = 1'bx,
|
|
|
|
parameter [0:0] PULLDOWN = 1'bx,
|
|
|
|
parameter [0:0] KEEPER = 1'bx,
|
|
|
|
parameter [0:0] SCHMITT_TRIGGER = 1'bx,
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_IBF = 1'bx,
|
|
|
|
parameter [3:0] DELAY_OBF = 1'bx,
|
|
|
|
parameter [0:0] FF_IBF = 1'bx,
|
|
|
|
parameter [0:0] FF_OBF = 1'bx
|
|
|
|
)(
|
|
|
|
input A, T,
|
|
|
|
output Y,
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
inout IO
|
|
|
|
);
|
|
|
|
assign IO = T ? 1'bz : A;
|
|
|
|
assign Y = IO;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(A => Y) = (0:0:0, 0:0:0);
|
|
|
|
(T => Y) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LVDS_IBUF #(
|
|
|
|
parameter PIN_NAME_P = "UNPLACED",
|
|
|
|
parameter PIN_NAME_N = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter [0:0] LVDS_RTERM = 1'bx,
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_IBF = 1'bx,
|
|
|
|
parameter [0:0] FF_IBF = 1'bx
|
|
|
|
)(
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
input IP, IN,
|
|
|
|
output Y
|
|
|
|
);
|
|
|
|
assign Y = IP;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(IP => Y) = (0:0:0, 0:0:0);
|
|
|
|
(IN => Y) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LVDS_OBUF #(
|
|
|
|
parameter PIN_NAME_P = "UNPLACED",
|
|
|
|
parameter PIN_NAME_N = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter [0:0] LVDS_BOOST = 1'bx,
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_OBF = 1'bx,
|
|
|
|
parameter [0:0] FF_OBF = 1'bx
|
|
|
|
)(
|
|
|
|
input A,
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
output OP, ON
|
|
|
|
);
|
|
|
|
assign OP = A;
|
|
|
|
assign ON = ~A;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(A => OP) = (0:0:0, 0:0:0);
|
|
|
|
(A => ON) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LVDS_TOBUF #(
|
|
|
|
parameter PIN_NAME_P = "UNPLACED",
|
|
|
|
parameter PIN_NAME_N = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter [0:0] LVDS_BOOST = 1'bx,
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_OBF = 1'bx,
|
|
|
|
parameter [0:0] FF_OBF = 1'bx
|
|
|
|
)(
|
|
|
|
input A, T,
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
output OP, ON
|
|
|
|
);
|
|
|
|
assign OP = T ? 1'bz : A;
|
|
|
|
assign ON = T ? 1'bz : ~A;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(A => OP) = (0:0:0, 0:0:0);
|
|
|
|
(A => OP) = (0:0:0, 0:0:0);
|
|
|
|
(A => ON) = (0:0:0, 0:0:0);
|
|
|
|
(A => ON) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LVDS_IOBUF #(
|
|
|
|
parameter PIN_NAME_P = "UNPLACED",
|
|
|
|
parameter PIN_NAME_N = "UNPLACED",
|
|
|
|
parameter V_IO = "UNDEFINED",
|
|
|
|
parameter [0:0] LVDS_RTERM = 1'bx,
|
|
|
|
parameter [0:0] LVDS_BOOST = 1'bx,
|
|
|
|
// IOSEL
|
|
|
|
parameter [3:0] DELAY_IBF = 1'bx,
|
|
|
|
parameter [3:0] DELAY_OBF = 1'bx,
|
|
|
|
parameter [0:0] FF_IBF = 1'bx,
|
|
|
|
parameter [0:0] FF_OBF = 1'bx
|
|
|
|
)(
|
|
|
|
input A, T,
|
|
|
|
(* iopad_external_pin *)
|
|
|
|
inout IOP, ION,
|
|
|
|
output Y
|
|
|
|
);
|
|
|
|
assign IOP = T ? 1'bz : A;
|
|
|
|
assign ION = T ? 1'bz : ~A;
|
|
|
|
assign Y = IOP;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(A => Y) = (0:0:0, 0:0:0);
|
|
|
|
(A => IOP) = (0:0:0, 0:0:0);
|
|
|
|
(A => ION) = (0:0:0, 0:0:0);
|
|
|
|
(T => Y) = (0:0:0, 0:0:0);
|
|
|
|
(T => IOP) = (0:0:0, 0:0:0);
|
|
|
|
(T => ION) = (0:0:0, 0:0:0);
|
|
|
|
(IOP => Y) = (0:0:0, 0:0:0);
|
|
|
|
(ION => Y) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_IDDR #(
|
|
|
|
parameter [0:0] CLK_INV = 1'b0
|
|
|
|
)(
|
|
|
|
input D,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input CLK,
|
|
|
|
output reg Q0, Q1
|
|
|
|
);
|
|
|
|
wire clk;
|
|
|
|
assign clk = (CLK_INV) ? ~CLK : CLK;
|
|
|
|
|
|
|
|
always @(posedge clk)
|
|
|
|
begin
|
|
|
|
Q0 <= D;
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(negedge clk)
|
|
|
|
begin
|
|
|
|
Q1 <= D;
|
|
|
|
end
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_ODDR #(
|
|
|
|
parameter [0:0] CLK_INV = 1'b0
|
|
|
|
)(
|
|
|
|
input D0,
|
|
|
|
input D1,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input CLK,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input DDR,
|
|
|
|
output Q
|
|
|
|
);
|
|
|
|
wire clk;
|
|
|
|
assign clk = (CLK_INV) ? ~CLK : CLK;
|
|
|
|
|
|
|
|
reg q0, q1;
|
|
|
|
assign Q = (DDR) ? q0 : q1;
|
|
|
|
|
|
|
|
always @(posedge clk)
|
|
|
|
begin
|
|
|
|
q0 <= D0;
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(negedge clk)
|
|
|
|
begin
|
|
|
|
q1 <= D1;
|
|
|
|
end
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_DFF #(
|
|
|
|
parameter [0:0] CLK_INV = 1'b0,
|
|
|
|
parameter [0:0] EN_INV = 1'b0,
|
|
|
|
parameter [0:0] SR_INV = 1'b0,
|
|
|
|
parameter [0:0] SR_VAL = 1'b0
|
|
|
|
)(
|
|
|
|
input D,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input CLK,
|
|
|
|
input EN,
|
|
|
|
input SR,
|
|
|
|
output reg Q
|
|
|
|
);
|
|
|
|
wire clk, en, sr;
|
|
|
|
assign clk = (CLK_INV) ? ~CLK : CLK;
|
|
|
|
assign en = (EN_INV) ? ~EN : EN;
|
|
|
|
assign sr = (SR_INV) ? ~SR : SR;
|
|
|
|
|
2021-09-14 08:10:32 -05:00
|
|
|
initial Q = 1'bX;
|
2021-09-13 10:16:15 -05:00
|
|
|
|
|
|
|
always @(posedge clk or posedge sr)
|
|
|
|
begin
|
|
|
|
if (sr) begin
|
|
|
|
Q <= SR_VAL;
|
|
|
|
end
|
|
|
|
else if (en) begin
|
|
|
|
Q <= D;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_DLT #(
|
|
|
|
parameter [0:0] G_INV = 1'b0,
|
|
|
|
parameter [0:0] SR_INV = 1'b0,
|
|
|
|
parameter [0:0] SR_VAL = 1'b0
|
|
|
|
)(
|
|
|
|
input D,
|
|
|
|
input G,
|
|
|
|
input SR,
|
|
|
|
output reg Q
|
|
|
|
);
|
|
|
|
wire en, sr;
|
|
|
|
assign en = (G_INV) ? ~G : G;
|
|
|
|
assign sr = (SR_INV) ? ~SR : SR;
|
|
|
|
|
2021-09-14 08:10:32 -05:00
|
|
|
initial Q = 1'bX;
|
2021-09-13 10:16:15 -05:00
|
|
|
|
|
|
|
always @(*)
|
|
|
|
begin
|
|
|
|
if (sr) begin
|
|
|
|
Q <= SR_VAL;
|
|
|
|
end
|
|
|
|
else if (en) begin
|
|
|
|
Q <= D;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LUT1 (
|
|
|
|
output O,
|
|
|
|
input I0
|
|
|
|
);
|
|
|
|
parameter [1:0] INIT = 0;
|
|
|
|
|
|
|
|
assign O = I0 ? INIT[1] : INIT[0];
|
|
|
|
|
|
|
|
specify
|
|
|
|
(I0 => O) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LUT2 (
|
|
|
|
output O,
|
|
|
|
input I0, I1
|
|
|
|
);
|
|
|
|
parameter [3:0] INIT = 0;
|
|
|
|
|
|
|
|
wire [1:0] s1 = I1 ? INIT[3:2] : INIT[1:0];
|
|
|
|
assign O = I0 ? s1[1] : s1[0];
|
|
|
|
|
|
|
|
specify
|
|
|
|
(I0 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I1 => O) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LUT3 (
|
|
|
|
output O,
|
|
|
|
input I0, I1, I2
|
|
|
|
);
|
|
|
|
parameter [7:0] INIT = 0;
|
|
|
|
|
|
|
|
wire [3:0] s2 = I2 ? INIT[7:4] : INIT[3:0];
|
|
|
|
wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
|
|
|
|
assign O = I0 ? s1[1] : s1[0];
|
|
|
|
|
|
|
|
specify
|
|
|
|
(I0 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I1 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I2 => O) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_LUT4 (
|
|
|
|
output O,
|
|
|
|
input I0, I1, I2, I3
|
|
|
|
);
|
|
|
|
parameter [15:0] INIT = 0;
|
|
|
|
|
|
|
|
wire [7:0] s3 = I3 ? INIT[15:8] : INIT[7:0];
|
|
|
|
wire [3:0] s2 = I2 ? s3[7:4] : s3[3:0];
|
|
|
|
wire [1:0] s1 = I1 ? s2[3:2] : s2[1:0];
|
|
|
|
assign O = I0 ? s1[1] : s1[0];
|
|
|
|
|
|
|
|
specify
|
|
|
|
(I0 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I1 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I2 => O) = (0:0:0, 0:0:0);
|
|
|
|
(I3 => O) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_MX2 (
|
|
|
|
input D0, D1,
|
|
|
|
input S0,
|
2021-09-14 08:10:32 -05:00
|
|
|
output Y
|
2021-09-13 10:16:15 -05:00
|
|
|
);
|
2021-09-14 08:10:32 -05:00
|
|
|
assign Y = S0 ? D1 : D0;
|
2021-09-13 10:16:15 -05:00
|
|
|
|
|
|
|
specify
|
|
|
|
(D0 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D1 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(S0 => Y) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_MX4 (
|
|
|
|
input D0, D1, D2, D3,
|
|
|
|
input S0, S1,
|
2021-09-14 08:10:32 -05:00
|
|
|
output Y
|
2021-09-13 10:16:15 -05:00
|
|
|
);
|
2021-09-14 08:10:32 -05:00
|
|
|
assign Y = S1 ? (S0 ? D3 : D2) :
|
|
|
|
(S0 ? D1 : D0);
|
2021-09-13 10:16:15 -05:00
|
|
|
|
|
|
|
specify
|
|
|
|
(D0 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D1 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D2 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D3 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(S0 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(S1 => Y) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_MX8 (
|
|
|
|
input D0, D1, D2, D3,
|
|
|
|
input D4, D5, D6, D7,
|
|
|
|
input S0, S1, S2,
|
2021-09-14 08:10:32 -05:00
|
|
|
output Y
|
2021-09-13 10:16:15 -05:00
|
|
|
);
|
2021-09-14 08:10:32 -05:00
|
|
|
assign Y = S2 ? (S1 ? (S0 ? D7 : D6) :
|
|
|
|
(S0 ? D5 : D4)) :
|
|
|
|
(S1 ? (S0 ? D3 : D2) :
|
|
|
|
(S0 ? D1 : D0));
|
2021-09-13 10:16:15 -05:00
|
|
|
|
|
|
|
specify
|
|
|
|
(D0 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D1 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D2 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D3 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D4 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D5 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D6 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(D7 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(S0 => Y) = (0:0:0, 0:0:0);
|
|
|
|
(S1 => Y) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_ADDF (
|
|
|
|
input A, B, CI,
|
|
|
|
output CO, S
|
|
|
|
);
|
|
|
|
assign {CO, S} = A + B + CI;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(A => S) = (0:0:0, 0:0:0);
|
|
|
|
(B => S) = (0:0:0, 0:0:0);
|
|
|
|
(CI => S) = (0:0:0, 0:0:0);
|
|
|
|
(A => CO) = (0:0:0, 0:0:0);
|
|
|
|
(B => CO) = (0:0:0, 0:0:0);
|
|
|
|
(CI => CO) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_MULT #(
|
|
|
|
parameter A_WIDTH = 0,
|
|
|
|
parameter B_WIDTH = 0,
|
|
|
|
parameter P_WIDTH = 0
|
|
|
|
)(
|
|
|
|
input signed [A_WIDTH-1:0] A,
|
|
|
|
input signed [B_WIDTH-1:0] B,
|
|
|
|
output reg signed [P_WIDTH-1:0] P
|
|
|
|
);
|
|
|
|
always @(*)
|
|
|
|
begin
|
|
|
|
P <= A * B;
|
|
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_BUFG (
|
|
|
|
input I,
|
|
|
|
(* clkbuf_driver *)
|
|
|
|
output O
|
|
|
|
);
|
|
|
|
assign O = I;
|
|
|
|
|
|
|
|
specify
|
|
|
|
(I => O) = (0:0:0, 0:0:0);
|
|
|
|
endspecify
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_BRAM_20K (
|
|
|
|
output [19:0] A_DO,
|
|
|
|
output [19:0] B_DO,
|
|
|
|
output ECC_1B_ERR,
|
|
|
|
output ECC_2B_ERR,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input A_CLK,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input B_CLK,
|
|
|
|
input A_EN,
|
|
|
|
input B_EN,
|
|
|
|
input A_WE,
|
|
|
|
input B_WE,
|
|
|
|
input [15:0] A_ADDR,
|
|
|
|
input [15:0] B_ADDR,
|
|
|
|
input [19:0] A_DI,
|
|
|
|
input [19:0] B_DI,
|
|
|
|
input [19:0] A_BM,
|
|
|
|
input [19:0] B_BM
|
|
|
|
);
|
|
|
|
// Location format: D(0..N-1)(0..N-1)X(0..3)Y(0..7)Z(0..1) or UNPLACED
|
|
|
|
parameter LOC = "UNPLACED";
|
|
|
|
|
|
|
|
// Port Widths
|
|
|
|
parameter A_RD_WIDTH = 0;
|
|
|
|
parameter B_RD_WIDTH = 0;
|
|
|
|
parameter A_WR_WIDTH = 0;
|
|
|
|
parameter B_WR_WIDTH = 0;
|
|
|
|
|
|
|
|
// RAM and Write Modes
|
|
|
|
parameter RAM_MODE = "SDP";
|
|
|
|
parameter A_WR_MODE = "NO_CHANGE";
|
|
|
|
parameter B_WR_MODE = "NO_CHANGE";
|
|
|
|
|
|
|
|
// Inverting Control Pins
|
|
|
|
parameter A_CLK_INV = 1'b0;
|
|
|
|
parameter B_CLK_INV = 1'b0;
|
|
|
|
parameter A_EN_INV = 1'b0;
|
|
|
|
parameter B_EN_INV = 1'b0;
|
|
|
|
parameter A_WE_INV = 1'b0;
|
|
|
|
parameter B_WE_INV = 1'b0;
|
|
|
|
|
|
|
|
// Output Register
|
|
|
|
parameter A_DO_REG = 1'b0;
|
|
|
|
parameter B_DO_REG = 1'b0;
|
|
|
|
|
|
|
|
// Error Checking and Correction
|
|
|
|
parameter ECC_EN = 1'b0;
|
|
|
|
|
|
|
|
// RAM Contents
|
|
|
|
parameter INIT_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
|
|
|
|
localparam WIDTH_MODE_A = (A_RD_WIDTH > A_WR_WIDTH) ? A_RD_WIDTH : A_WR_WIDTH;
|
|
|
|
localparam WIDTH_MODE_B = (B_RD_WIDTH > B_WR_WIDTH) ? B_RD_WIDTH : B_WR_WIDTH;
|
|
|
|
|
|
|
|
integer i, k;
|
|
|
|
|
|
|
|
// 512 x 40 bit
|
|
|
|
reg [20479:0] memory = 20480'b0;
|
|
|
|
|
|
|
|
initial begin
|
|
|
|
// Check parameters
|
|
|
|
if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin
|
|
|
|
$display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((A_WR_MODE != "WRITE_THROUGH") && (A_WR_MODE != "NO_CHANGE")) begin
|
|
|
|
$display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((RAM_MODE == "SDP") && (A_WR_MODE == "WRITE_THROUGH")) begin
|
|
|
|
$display("ERROR: %s is not supported in %s mode.", A_WR_MODE, RAM_MODE);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if (ECC_EN != 1'b0) begin
|
|
|
|
$display("WARNING: ECC feature not supported in simulation.");
|
|
|
|
end
|
|
|
|
if ((ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (WIDTH_MODE_A != 40)) begin
|
|
|
|
$display("ERROR: Illegal ECC Port configuration. Must be SDP 40 bit, but is %s %d.", RAM_MODE, WIDTH_MODE_A);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_A == 40) && (RAM_MODE == "TDP")) begin
|
|
|
|
$display("ERROR: Port A width of 40 bits is only supported in SDP mode.");
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_B == 40) && (RAM_MODE == "TDP")) begin
|
|
|
|
$display("ERROR: Port B width of 40 bits is only supported in SDP mode.");
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_A != 40) && (WIDTH_MODE_A != 20) && (WIDTH_MODE_A != 10) &&
|
|
|
|
(WIDTH_MODE_A != 5) && (WIDTH_MODE_A != 2) && (WIDTH_MODE_A != 1) && (WIDTH_MODE_A != 0)) begin
|
|
|
|
$display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, WIDTH_MODE_A);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_B != 40) && (WIDTH_MODE_B != 20) && (WIDTH_MODE_B != 10) &&
|
|
|
|
(WIDTH_MODE_B != 5) && (WIDTH_MODE_B != 2) && (WIDTH_MODE_B != 1) && (WIDTH_MODE_B != 0)) begin
|
|
|
|
$display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, WIDTH_MODE_B);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
// RAM initialization
|
|
|
|
for (i=0; i < 320; i=i+1) begin
|
|
|
|
memory[320*0+i] = INIT_00[i];
|
|
|
|
memory[320*1+i] = INIT_01[i];
|
|
|
|
memory[320*2+i] = INIT_02[i];
|
|
|
|
memory[320*3+i] = INIT_03[i];
|
|
|
|
memory[320*4+i] = INIT_04[i];
|
|
|
|
memory[320*5+i] = INIT_05[i];
|
|
|
|
memory[320*6+i] = INIT_06[i];
|
|
|
|
memory[320*7+i] = INIT_07[i];
|
|
|
|
memory[320*8+i] = INIT_08[i];
|
|
|
|
memory[320*9+i] = INIT_09[i];
|
|
|
|
memory[320*10+i] = INIT_0A[i];
|
|
|
|
memory[320*11+i] = INIT_0B[i];
|
|
|
|
memory[320*12+i] = INIT_0C[i];
|
|
|
|
memory[320*13+i] = INIT_0D[i];
|
|
|
|
memory[320*14+i] = INIT_0E[i];
|
|
|
|
memory[320*15+i] = INIT_0F[i];
|
|
|
|
memory[320*16+i] = INIT_10[i];
|
|
|
|
memory[320*17+i] = INIT_11[i];
|
|
|
|
memory[320*18+i] = INIT_12[i];
|
|
|
|
memory[320*19+i] = INIT_13[i];
|
|
|
|
memory[320*20+i] = INIT_14[i];
|
|
|
|
memory[320*21+i] = INIT_15[i];
|
|
|
|
memory[320*22+i] = INIT_16[i];
|
|
|
|
memory[320*23+i] = INIT_17[i];
|
|
|
|
memory[320*24+i] = INIT_18[i];
|
|
|
|
memory[320*25+i] = INIT_19[i];
|
|
|
|
memory[320*26+i] = INIT_1A[i];
|
|
|
|
memory[320*27+i] = INIT_1B[i];
|
|
|
|
memory[320*28+i] = INIT_1C[i];
|
|
|
|
memory[320*29+i] = INIT_1D[i];
|
|
|
|
memory[320*30+i] = INIT_1E[i];
|
|
|
|
memory[320*31+i] = INIT_1F[i];
|
|
|
|
memory[320*32+i] = INIT_20[i];
|
|
|
|
memory[320*33+i] = INIT_21[i];
|
|
|
|
memory[320*34+i] = INIT_22[i];
|
|
|
|
memory[320*35+i] = INIT_23[i];
|
|
|
|
memory[320*36+i] = INIT_24[i];
|
|
|
|
memory[320*37+i] = INIT_25[i];
|
|
|
|
memory[320*38+i] = INIT_26[i];
|
|
|
|
memory[320*39+i] = INIT_27[i];
|
|
|
|
memory[320*30+i] = INIT_28[i];
|
|
|
|
memory[320*41+i] = INIT_29[i];
|
|
|
|
memory[320*42+i] = INIT_2A[i];
|
|
|
|
memory[320*43+i] = INIT_2B[i];
|
|
|
|
memory[320*44+i] = INIT_2C[i];
|
|
|
|
memory[320*45+i] = INIT_2D[i];
|
|
|
|
memory[320*46+i] = INIT_2E[i];
|
|
|
|
memory[320*47+i] = INIT_2F[i];
|
|
|
|
memory[320*48+i] = INIT_30[i];
|
|
|
|
memory[320*49+i] = INIT_31[i];
|
|
|
|
memory[320*50+i] = INIT_32[i];
|
|
|
|
memory[320*51+i] = INIT_33[i];
|
|
|
|
memory[320*52+i] = INIT_34[i];
|
|
|
|
memory[320*53+i] = INIT_35[i];
|
|
|
|
memory[320*54+i] = INIT_36[i];
|
|
|
|
memory[320*55+i] = INIT_37[i];
|
|
|
|
memory[320*56+i] = INIT_38[i];
|
|
|
|
memory[320*57+i] = INIT_39[i];
|
|
|
|
memory[320*58+i] = INIT_3A[i];
|
|
|
|
memory[320*59+i] = INIT_3B[i];
|
|
|
|
memory[320*60+i] = INIT_3C[i];
|
|
|
|
memory[320*61+i] = INIT_3D[i];
|
|
|
|
memory[320*62+i] = INIT_3E[i];
|
|
|
|
memory[320*63+i] = INIT_3F[i];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
// Signal inversion
|
|
|
|
wire clka = A_CLK_INV ^ A_CLK;
|
|
|
|
wire clkb = B_CLK_INV ^ B_CLK;
|
|
|
|
wire ena = A_EN_INV ^ A_EN;
|
|
|
|
wire enb = B_EN_INV ^ B_EN;
|
|
|
|
wire wea = A_WE_INV ^ A_WE;
|
|
|
|
wire web = B_WE_INV ^ B_WE;
|
|
|
|
|
|
|
|
// Internal signals
|
|
|
|
wire [15:0] addra;
|
|
|
|
wire [15:0] addrb;
|
|
|
|
reg [19:0] A_DO_out = 0, A_DO_reg = 0;
|
|
|
|
reg [19:0] B_DO_out = 0, B_DO_reg = 0;
|
|
|
|
|
|
|
|
generate
|
|
|
|
if (RAM_MODE == "SDP") begin
|
|
|
|
// Port A (write)
|
|
|
|
if (WIDTH_MODE_A <= 1) begin
|
|
|
|
assign addra = A_ADDR[15:7] + (A_ADDR[15:7]/4);
|
|
|
|
end
|
|
|
|
if (WIDTH_MODE_A <= 2) begin
|
|
|
|
assign addra = A_ADDR[15:7]*2 + (A_ADDR[15:7]/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 5) begin
|
|
|
|
assign addra = A_ADDR[15:7]*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 10) begin
|
|
|
|
assign addra = A_ADDR[15:7]*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 20) begin
|
|
|
|
assign addra = A_ADDR[15:7]*20;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 40) begin
|
|
|
|
assign addra = A_ADDR[15:7]*40;
|
|
|
|
end
|
|
|
|
// Port B (read)
|
|
|
|
if (WIDTH_MODE_B <= 1) begin
|
|
|
|
assign addrb = B_ADDR[15:7] + (B_ADDR[15:7]/4);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 2) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*2 + (B_ADDR[15:7]/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 5) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 10) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 20) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*20;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 40) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*40;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if (RAM_MODE == "TDP") begin
|
|
|
|
// Port A
|
|
|
|
if (WIDTH_MODE_A <= 1) begin
|
|
|
|
wire [15:0] tmpa = {2'b0, A_ADDR[15:7], A_ADDR[5:1]};
|
|
|
|
assign addra = tmpa + (tmpa/4);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 2) begin
|
|
|
|
wire [15:0] tmpa = {3'b0, A_ADDR[15:7], A_ADDR[5:2]};
|
|
|
|
assign addra = tmpa*2 + (tmpa/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 5) begin
|
|
|
|
assign addra = {4'b0, A_ADDR[15:7], A_ADDR[5:3]}*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 10) begin
|
|
|
|
assign addra = {5'b0, A_ADDR[15:7], A_ADDR[5:4]}*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 20) begin
|
|
|
|
assign addra = {6'b0, A_ADDR[15:7], A_ADDR[5]}*20;
|
|
|
|
end
|
|
|
|
// Port B
|
|
|
|
if (WIDTH_MODE_B <= 1) begin
|
|
|
|
wire [15:0] tmpb = {2'b0, B_ADDR[15:7], B_ADDR[5:1]};
|
|
|
|
assign addrb = tmpb + (tmpb/4);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 2) begin
|
|
|
|
wire [15:0] tmpb = {3'b0, B_ADDR[15:7], B_ADDR[5:2]};
|
|
|
|
assign addrb = tmpb*2 + (tmpb/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 5) begin
|
|
|
|
assign addrb = {4'b0, B_ADDR[15:7], B_ADDR[5:3]}*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 10) begin
|
|
|
|
assign addrb = {5'b0, B_ADDR[15:7], B_ADDR[5:4]}*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 20) begin
|
|
|
|
assign addrb = {6'b0, B_ADDR[15:7], B_ADDR[5]}*20;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
|
|
|
|
generate
|
|
|
|
if (RAM_MODE == "SDP") begin
|
|
|
|
// SDP write port
|
|
|
|
always @(posedge clka)
|
|
|
|
begin
|
|
|
|
for (k=0; k < WIDTH_MODE_A; k=k+1) begin
|
|
|
|
if (k < 20) begin
|
|
|
|
if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
|
|
|
|
end
|
|
|
|
else begin // use both ports
|
|
|
|
if (ena && wea && B_BM[k-20]) memory[addra+k] <= B_DI[k-20];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
// SDP read port
|
|
|
|
always @(posedge clkb)
|
|
|
|
begin
|
|
|
|
for (k=0; k < WIDTH_MODE_B; k=k+1) begin
|
|
|
|
if (k < 20) begin
|
|
|
|
if (enb) A_DO_out[k] <= memory[addrb+k];
|
|
|
|
end
|
|
|
|
else begin // use both ports
|
|
|
|
if (enb) B_DO_out[k-20] <= memory[addrb+k];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if (RAM_MODE == "TDP") begin
|
|
|
|
// TDP port A
|
|
|
|
always @(posedge clka)
|
|
|
|
begin
|
|
|
|
for (i=0; i < WIDTH_MODE_A; i=i+1) begin
|
|
|
|
if (ena && wea && A_BM[i]) memory[addra+i] <= A_DI[i];
|
|
|
|
|
|
|
|
if (A_WR_MODE == "NO_CHANGE") begin
|
|
|
|
if (ena) A_DO_out[i] <= memory[addra+i];
|
|
|
|
end
|
|
|
|
else if (A_WR_MODE == "WRITE_THROUGH") begin
|
|
|
|
if (ena) A_DO_out[i] <= A_DI[i];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
// TDP port B
|
|
|
|
always @(posedge clkb)
|
|
|
|
begin
|
|
|
|
for (i=0; i < WIDTH_MODE_B; i=i+1) begin
|
|
|
|
if (enb && web && B_BM[i]) memory[addrb+i] <= B_DI[i];
|
|
|
|
|
|
|
|
if (B_WR_MODE == "NO_CHANGE") begin
|
|
|
|
if (enb) B_DO_out[i] <= memory[addrb+i];
|
|
|
|
end
|
|
|
|
else if (B_WR_MODE == "WRITE_THROUGH") begin
|
|
|
|
if (enb) B_DO_out[i] <= B_DI[i];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
|
|
|
|
// Optional output register
|
|
|
|
generate
|
|
|
|
if (A_DO_REG) begin
|
|
|
|
always @(posedge clka) begin
|
|
|
|
A_DO_reg <= A_DO_out;
|
|
|
|
end
|
|
|
|
assign A_DO = A_DO_reg;
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
assign A_DO = A_DO_out;
|
|
|
|
end
|
|
|
|
if (B_DO_REG) begin
|
|
|
|
always @(posedge clkb) begin
|
|
|
|
B_DO_reg <= B_DO_out;
|
|
|
|
end
|
|
|
|
assign B_DO = B_DO_reg;
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
assign B_DO = B_DO_out;
|
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
module CC_BRAM_40K (
|
|
|
|
output [39:0] A_DO,
|
|
|
|
output [39:0] B_DO,
|
|
|
|
output A_ECC_1B_ERR,
|
|
|
|
output B_ECC_1B_ERR,
|
|
|
|
output A_ECC_2B_ERR,
|
|
|
|
output B_ECC_2B_ERR,
|
|
|
|
output A_CO,
|
|
|
|
output B_CO,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input A_CLK,
|
|
|
|
(* clkbuf_sink *)
|
|
|
|
input B_CLK,
|
|
|
|
input A_EN,
|
|
|
|
input B_EN,
|
|
|
|
input A_WE,
|
|
|
|
input B_WE,
|
|
|
|
input [15:0] A_ADDR,
|
|
|
|
input [15:0] B_ADDR,
|
|
|
|
input [39:0] A_DI,
|
|
|
|
input [39:0] B_DI,
|
|
|
|
input [39:0] A_BM,
|
|
|
|
input [39:0] B_BM,
|
|
|
|
input A_CI,
|
|
|
|
input B_CI
|
|
|
|
);
|
|
|
|
// Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED
|
|
|
|
parameter LOC = "UNPLACED";
|
|
|
|
parameter CAS = "NONE"; // NONE, UPPER, LOWER
|
|
|
|
|
|
|
|
// Port Widths
|
|
|
|
parameter A_RD_WIDTH = 0;
|
|
|
|
parameter B_RD_WIDTH = 0;
|
|
|
|
parameter A_WR_WIDTH = 0;
|
|
|
|
parameter B_WR_WIDTH = 0;
|
|
|
|
|
|
|
|
// RAM and Write Modes
|
|
|
|
parameter RAM_MODE = "SDP";
|
|
|
|
parameter A_WR_MODE = "NO_CHANGE";
|
|
|
|
parameter B_WR_MODE = "NO_CHANGE";
|
|
|
|
|
|
|
|
// Inverting Control Pins
|
|
|
|
parameter A_CLK_INV = 1'b0;
|
|
|
|
parameter B_CLK_INV = 1'b0;
|
|
|
|
parameter A_EN_INV = 1'b0;
|
|
|
|
parameter B_EN_INV = 1'b0;
|
|
|
|
parameter A_WE_INV = 1'b0;
|
|
|
|
parameter B_WE_INV = 1'b0;
|
|
|
|
|
|
|
|
// Output Register
|
|
|
|
parameter A_DO_REG = 1'b0;
|
|
|
|
parameter B_DO_REG = 1'b0;
|
|
|
|
|
|
|
|
// Error Checking and Correction
|
|
|
|
parameter A_ECC_EN = 1'b0;
|
|
|
|
parameter B_ECC_EN = 1'b0;
|
|
|
|
|
|
|
|
parameter INIT_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_40 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_41 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_42 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_43 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_44 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_45 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_46 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_47 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_48 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_49 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_4A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_4B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_4C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_4D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_4E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_4F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_50 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_51 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_52 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_53 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_54 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_55 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_56 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_57 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_58 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_59 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_5A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_5B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_5C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_5D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_5E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_5F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_60 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_61 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_62 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_63 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_64 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_65 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_66 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_67 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_68 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_69 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_6A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_6B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_6C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_6D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_6E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_6F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_70 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_71 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_72 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_73 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_74 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_75 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_76 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_77 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_78 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_79 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_7A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_7B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_7C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_7D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_7E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
parameter INIT_7F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
|
|
|
|
|
|
|
localparam WIDTH_MODE_A = (A_RD_WIDTH > A_WR_WIDTH) ? A_RD_WIDTH : A_WR_WIDTH;
|
|
|
|
localparam WIDTH_MODE_B = (B_RD_WIDTH > B_WR_WIDTH) ? B_RD_WIDTH : B_WR_WIDTH;
|
|
|
|
|
|
|
|
integer i, k;
|
|
|
|
|
|
|
|
// 512 x 80 bit
|
|
|
|
reg [40959:0] memory = 40960'b0;
|
|
|
|
|
|
|
|
initial begin
|
|
|
|
// Check parameters
|
|
|
|
if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin
|
|
|
|
$display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((A_WR_MODE != "WRITE_THROUGH") && (A_WR_MODE != "NO_CHANGE")) begin
|
|
|
|
$display("ERROR: Illegal RAM MODE %d.", RAM_MODE);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((RAM_MODE == "SDP") && (A_WR_MODE == "WRITE_THROUGH")) begin
|
|
|
|
$display("ERROR: %s is not supported in %s mode.", A_WR_MODE, RAM_MODE);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((A_ECC_EN != 1'b0) || (B_ECC_EN != 1'b0)) begin
|
|
|
|
$display("WARNING: ECC feature not supported in simulation.");
|
|
|
|
end
|
|
|
|
if ((A_ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (WIDTH_MODE_A != 40)) begin
|
|
|
|
$display("ERROR: Illegal ECC Port A configuration. Must be SDP 40 bit, but is %s %d.", RAM_MODE, WIDTH_MODE_A);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_A == 80) && (RAM_MODE == "TDP")) begin
|
|
|
|
$display("ERROR: Port A width of 80 bits is only supported in SDP mode.");
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_B == 80) && (RAM_MODE == "TDP")) begin
|
|
|
|
$display("ERROR: Port B width of 80 bits is only supported in SDP mode.");
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_A != 80) && (WIDTH_MODE_A != 40) && (WIDTH_MODE_A != 20) && (WIDTH_MODE_A != 10) &&
|
|
|
|
(WIDTH_MODE_A != 5) && (WIDTH_MODE_A != 2) && (WIDTH_MODE_A != 1) && (WIDTH_MODE_A != 0)) begin
|
|
|
|
$display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, WIDTH_MODE_A);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((WIDTH_MODE_B != 80) && (WIDTH_MODE_B != 40) && (WIDTH_MODE_B != 20) && (WIDTH_MODE_B != 10) &&
|
|
|
|
(WIDTH_MODE_B != 5) && (WIDTH_MODE_B != 2) && (WIDTH_MODE_B != 1) && (WIDTH_MODE_B != 0)) begin
|
|
|
|
$display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, WIDTH_MODE_B);
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((CAS != "NONE") && ((WIDTH_MODE_A > 1) || (WIDTH_MODE_B > 1))) begin
|
|
|
|
$display("ERROR: Cascade feature only supported in 1 bit data width mode.");
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
if ((CAS != "NONE") && (RAM_MODE != "TDP")) begin
|
|
|
|
$display("ERROR: Cascade feature only supported in TDP mode.");
|
|
|
|
$finish();
|
|
|
|
end
|
|
|
|
// RAM initialization
|
|
|
|
for (i=0; i < 320; i=i+1) begin
|
|
|
|
memory[320*0+i] = INIT_00[i];
|
|
|
|
memory[320*1+i] = INIT_01[i];
|
|
|
|
memory[320*2+i] = INIT_02[i];
|
|
|
|
memory[320*3+i] = INIT_03[i];
|
|
|
|
memory[320*4+i] = INIT_04[i];
|
|
|
|
memory[320*5+i] = INIT_05[i];
|
|
|
|
memory[320*6+i] = INIT_06[i];
|
|
|
|
memory[320*7+i] = INIT_07[i];
|
|
|
|
memory[320*8+i] = INIT_08[i];
|
|
|
|
memory[320*9+i] = INIT_09[i];
|
|
|
|
memory[320*10+i] = INIT_0A[i];
|
|
|
|
memory[320*11+i] = INIT_0B[i];
|
|
|
|
memory[320*12+i] = INIT_0C[i];
|
|
|
|
memory[320*13+i] = INIT_0D[i];
|
|
|
|
memory[320*14+i] = INIT_0E[i];
|
|
|
|
memory[320*15+i] = INIT_0F[i];
|
|
|
|
memory[320*16+i] = INIT_10[i];
|
|
|
|
memory[320*17+i] = INIT_11[i];
|
|
|
|
memory[320*18+i] = INIT_12[i];
|
|
|
|
memory[320*19+i] = INIT_13[i];
|
|
|
|
memory[320*20+i] = INIT_14[i];
|
|
|
|
memory[320*21+i] = INIT_15[i];
|
|
|
|
memory[320*22+i] = INIT_16[i];
|
|
|
|
memory[320*23+i] = INIT_17[i];
|
|
|
|
memory[320*24+i] = INIT_18[i];
|
|
|
|
memory[320*25+i] = INIT_19[i];
|
|
|
|
memory[320*26+i] = INIT_1A[i];
|
|
|
|
memory[320*27+i] = INIT_1B[i];
|
|
|
|
memory[320*28+i] = INIT_1C[i];
|
|
|
|
memory[320*29+i] = INIT_1D[i];
|
|
|
|
memory[320*30+i] = INIT_1E[i];
|
|
|
|
memory[320*31+i] = INIT_1F[i];
|
|
|
|
memory[320*32+i] = INIT_20[i];
|
|
|
|
memory[320*33+i] = INIT_21[i];
|
|
|
|
memory[320*34+i] = INIT_22[i];
|
|
|
|
memory[320*35+i] = INIT_23[i];
|
|
|
|
memory[320*36+i] = INIT_24[i];
|
|
|
|
memory[320*37+i] = INIT_25[i];
|
|
|
|
memory[320*38+i] = INIT_26[i];
|
|
|
|
memory[320*39+i] = INIT_27[i];
|
|
|
|
memory[320*30+i] = INIT_28[i];
|
|
|
|
memory[320*41+i] = INIT_29[i];
|
|
|
|
memory[320*42+i] = INIT_2A[i];
|
|
|
|
memory[320*43+i] = INIT_2B[i];
|
|
|
|
memory[320*44+i] = INIT_2C[i];
|
|
|
|
memory[320*45+i] = INIT_2D[i];
|
|
|
|
memory[320*46+i] = INIT_2E[i];
|
|
|
|
memory[320*47+i] = INIT_2F[i];
|
|
|
|
memory[320*48+i] = INIT_30[i];
|
|
|
|
memory[320*49+i] = INIT_31[i];
|
|
|
|
memory[320*50+i] = INIT_32[i];
|
|
|
|
memory[320*51+i] = INIT_33[i];
|
|
|
|
memory[320*52+i] = INIT_34[i];
|
|
|
|
memory[320*53+i] = INIT_35[i];
|
|
|
|
memory[320*54+i] = INIT_36[i];
|
|
|
|
memory[320*55+i] = INIT_37[i];
|
|
|
|
memory[320*56+i] = INIT_38[i];
|
|
|
|
memory[320*57+i] = INIT_39[i];
|
|
|
|
memory[320*58+i] = INIT_3A[i];
|
|
|
|
memory[320*59+i] = INIT_3B[i];
|
|
|
|
memory[320*60+i] = INIT_3C[i];
|
|
|
|
memory[320*61+i] = INIT_3D[i];
|
|
|
|
memory[320*62+i] = INIT_3E[i];
|
|
|
|
memory[320*63+i] = INIT_3F[i];
|
|
|
|
memory[320*64+i] = INIT_40[i];
|
|
|
|
memory[320*65+i] = INIT_41[i];
|
|
|
|
memory[320*66+i] = INIT_42[i];
|
|
|
|
memory[320*67+i] = INIT_43[i];
|
|
|
|
memory[320*68+i] = INIT_44[i];
|
|
|
|
memory[320*69+i] = INIT_45[i];
|
|
|
|
memory[320*70+i] = INIT_46[i];
|
|
|
|
memory[320*71+i] = INIT_47[i];
|
|
|
|
memory[320*72+i] = INIT_48[i];
|
|
|
|
memory[320*73+i] = INIT_49[i];
|
|
|
|
memory[320*74+i] = INIT_4A[i];
|
|
|
|
memory[320*75+i] = INIT_4B[i];
|
|
|
|
memory[320*76+i] = INIT_4C[i];
|
|
|
|
memory[320*77+i] = INIT_4D[i];
|
|
|
|
memory[320*78+i] = INIT_4E[i];
|
|
|
|
memory[320*79+i] = INIT_4F[i];
|
|
|
|
memory[320*80+i] = INIT_50[i];
|
|
|
|
memory[320*81+i] = INIT_51[i];
|
|
|
|
memory[320*82+i] = INIT_52[i];
|
|
|
|
memory[320*83+i] = INIT_53[i];
|
|
|
|
memory[320*84+i] = INIT_54[i];
|
|
|
|
memory[320*85+i] = INIT_55[i];
|
|
|
|
memory[320*86+i] = INIT_56[i];
|
|
|
|
memory[320*87+i] = INIT_57[i];
|
|
|
|
memory[320*88+i] = INIT_58[i];
|
|
|
|
memory[320*89+i] = INIT_59[i];
|
|
|
|
memory[320*90+i] = INIT_5A[i];
|
|
|
|
memory[320*91+i] = INIT_5B[i];
|
|
|
|
memory[320*92+i] = INIT_5C[i];
|
|
|
|
memory[320*93+i] = INIT_5D[i];
|
|
|
|
memory[320*94+i] = INIT_5E[i];
|
|
|
|
memory[320*95+i] = INIT_5F[i];
|
|
|
|
memory[320*96+i] = INIT_60[i];
|
|
|
|
memory[320*97+i] = INIT_61[i];
|
|
|
|
memory[320*98+i] = INIT_62[i];
|
|
|
|
memory[320*99+i] = INIT_63[i];
|
|
|
|
memory[320*100+i] = INIT_64[i];
|
|
|
|
memory[320*101+i] = INIT_65[i];
|
|
|
|
memory[320*102+i] = INIT_66[i];
|
|
|
|
memory[320*103+i] = INIT_67[i];
|
|
|
|
memory[320*104+i] = INIT_68[i];
|
|
|
|
memory[320*105+i] = INIT_69[i];
|
|
|
|
memory[320*106+i] = INIT_6A[i];
|
|
|
|
memory[320*107+i] = INIT_6B[i];
|
|
|
|
memory[320*108+i] = INIT_6C[i];
|
|
|
|
memory[320*109+i] = INIT_6D[i];
|
|
|
|
memory[320*110+i] = INIT_6E[i];
|
|
|
|
memory[320*111+i] = INIT_6F[i];
|
|
|
|
memory[320*112+i] = INIT_70[i];
|
|
|
|
memory[320*113+i] = INIT_71[i];
|
|
|
|
memory[320*114+i] = INIT_72[i];
|
|
|
|
memory[320*115+i] = INIT_73[i];
|
|
|
|
memory[320*116+i] = INIT_74[i];
|
|
|
|
memory[320*117+i] = INIT_75[i];
|
|
|
|
memory[320*118+i] = INIT_76[i];
|
|
|
|
memory[320*119+i] = INIT_77[i];
|
|
|
|
memory[320*120+i] = INIT_78[i];
|
|
|
|
memory[320*121+i] = INIT_79[i];
|
|
|
|
memory[320*122+i] = INIT_7A[i];
|
|
|
|
memory[320*123+i] = INIT_7B[i];
|
|
|
|
memory[320*124+i] = INIT_7C[i];
|
|
|
|
memory[320*125+i] = INIT_7D[i];
|
|
|
|
memory[320*126+i] = INIT_7E[i];
|
|
|
|
memory[320*127+i] = INIT_7F[i];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
// Signal inversion
|
|
|
|
wire clka = A_CLK_INV ^ A_CLK;
|
|
|
|
wire clkb = B_CLK_INV ^ B_CLK;
|
|
|
|
wire ena = A_EN_INV ^ A_EN;
|
|
|
|
wire enb = B_EN_INV ^ B_EN;
|
|
|
|
wire wea = A_WE_INV ^ A_WE;
|
|
|
|
wire web = B_WE_INV ^ B_WE;
|
|
|
|
|
|
|
|
// Internal signals
|
|
|
|
wire [15:0] addra;
|
|
|
|
wire [15:0] addrb;
|
|
|
|
reg [39:0] A_DO_out = 0, A_DO_reg = 0;
|
|
|
|
reg [39:0] B_DO_out = 0, B_DO_reg = 0;
|
|
|
|
|
|
|
|
generate
|
|
|
|
if (RAM_MODE == "SDP") begin
|
|
|
|
// Port A (write)
|
|
|
|
if (WIDTH_MODE_A <= 1) begin
|
|
|
|
assign addra = A_ADDR[15:7] + (A_ADDR[15:7]/4);
|
|
|
|
end
|
|
|
|
if (WIDTH_MODE_A <= 2) begin
|
|
|
|
assign addra = A_ADDR[15:7]*2 + (A_ADDR[15:7]/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 5) begin
|
|
|
|
assign addra = A_ADDR[15:7]*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 10) begin
|
|
|
|
assign addra = A_ADDR[15:7]*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 20) begin
|
|
|
|
assign addra = A_ADDR[15:7]*20;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 40) begin
|
|
|
|
assign addra = A_ADDR[15:7]*40;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 80) begin
|
|
|
|
assign addra = A_ADDR[15:7]*80;
|
|
|
|
end
|
|
|
|
// Port B (read)
|
|
|
|
if (WIDTH_MODE_B <= 1) begin
|
|
|
|
assign addrb = B_ADDR[15:7] + (B_ADDR[15:7]/4);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 2) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*2 + (B_ADDR[15:7]/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 5) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 10) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 20) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*20;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 40) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*40;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 80) begin
|
|
|
|
assign addrb = B_ADDR[15:7]*80;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if (RAM_MODE == "TDP") begin
|
|
|
|
// Port A
|
|
|
|
if (WIDTH_MODE_A <= 1) begin
|
|
|
|
wire [15:0] tmpa = {1'b0, A_ADDR[15:1]};
|
|
|
|
assign addra = tmpa + (tmpa/4);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 2) begin
|
|
|
|
wire [15:0] tmpa = {2'b0, A_ADDR[15:2]};
|
|
|
|
assign addra = tmpa*2 + (tmpa/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 5) begin
|
|
|
|
assign addra = {3'b0, A_ADDR[15:3]}*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 10) begin
|
|
|
|
assign addra = {4'b0, A_ADDR[15:4]}*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 20) begin
|
|
|
|
assign addra = {5'b0, A_ADDR[15:5]}*20;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_A <= 40) begin
|
|
|
|
assign addra = {6'b0, A_ADDR[15:6]}*40;
|
|
|
|
end
|
|
|
|
// Port B
|
|
|
|
if (WIDTH_MODE_B <= 1) begin
|
|
|
|
wire [15:0] tmpb = {1'b0, B_ADDR[15:1]};
|
|
|
|
assign addrb = tmpb + (tmpb/4);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 2) begin
|
|
|
|
wire [15:0] tmpb = {2'b0, B_ADDR[15:2]};
|
|
|
|
assign addrb = tmpb*2 + (tmpb/2);
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 5) begin
|
|
|
|
assign addrb = {3'b0, B_ADDR[15:3]}*5;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 10) begin
|
|
|
|
assign addrb = {4'b0, B_ADDR[15:4]}*10;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 20) begin
|
|
|
|
assign addrb = {5'b0, B_ADDR[15:5]}*20;
|
|
|
|
end
|
|
|
|
else if (WIDTH_MODE_B <= 40) begin
|
|
|
|
assign addrb = {6'b0, B_ADDR[15:6]}*40;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
|
|
|
|
generate
|
|
|
|
if (RAM_MODE == "SDP") begin
|
|
|
|
// SDP write port
|
|
|
|
always @(posedge clka)
|
|
|
|
begin
|
|
|
|
for (k=0; k < WIDTH_MODE_A; k=k+1) begin
|
|
|
|
if (k < 40) begin
|
|
|
|
if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
|
|
|
|
end
|
|
|
|
else begin // use both ports
|
|
|
|
if (ena && wea && B_BM[k-40]) memory[addra+k] <= B_DI[k-40];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
// SDP read port
|
|
|
|
always @(posedge clkb)
|
|
|
|
begin
|
|
|
|
for (k=0; k < WIDTH_MODE_B; k=k+1) begin
|
|
|
|
if (k < 40) begin
|
|
|
|
if (enb) A_DO_out[k] <= memory[addrb+k];
|
|
|
|
end
|
|
|
|
else begin // use both ports
|
|
|
|
if (enb) B_DO_out[k-40] <= memory[addrb+k];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else if (RAM_MODE == "TDP") begin
|
|
|
|
// TDP port A
|
|
|
|
always @(posedge clka)
|
|
|
|
begin
|
|
|
|
for (i=0; i < WIDTH_MODE_A; i=i+1) begin
|
|
|
|
if (ena && wea && A_BM[i]) memory[addra+i] <= A_DI[i];
|
|
|
|
|
|
|
|
if (A_WR_MODE == "NO_CHANGE") begin
|
|
|
|
if (ena) A_DO_out[i] <= memory[addra+i];
|
|
|
|
end
|
|
|
|
else if (A_WR_MODE == "WRITE_THROUGH") begin
|
|
|
|
if (ena) A_DO_out[i] <= A_DI[i];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
// TDP port B
|
|
|
|
always @(posedge clkb)
|
|
|
|
begin
|
|
|
|
for (i=0; i < WIDTH_MODE_B; i=i+1) begin
|
|
|
|
if (enb && web && B_BM[i]) memory[addrb+i] <= B_DI[i];
|
|
|
|
|
|
|
|
if (B_WR_MODE == "NO_CHANGE") begin
|
|
|
|
if (enb) B_DO_out[i] <= memory[addrb+i];
|
|
|
|
end
|
|
|
|
else if (B_WR_MODE == "WRITE_THROUGH") begin
|
|
|
|
if (enb) B_DO_out[i] <= B_DI[i];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
|
|
|
|
// Optional output register
|
|
|
|
generate
|
|
|
|
if (A_DO_REG) begin
|
|
|
|
always @(posedge clka) begin
|
|
|
|
A_DO_reg <= A_DO_out;
|
|
|
|
end
|
|
|
|
assign A_DO = A_DO_reg;
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
assign A_DO = A_DO_out;
|
|
|
|
end
|
|
|
|
if (B_DO_REG) begin
|
|
|
|
always @(posedge clkb) begin
|
|
|
|
B_DO_reg <= B_DO_out;
|
|
|
|
end
|
|
|
|
assign B_DO = B_DO_reg;
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
assign B_DO = B_DO_out;
|
|
|
|
end
|
|
|
|
endgenerate
|
|
|
|
endmodule
|