/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2021 Cologne Chip AG * * 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; initial Q = 0; 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; initial Q = 0; 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, output reg Y ); always @(*) begin case (S0) 1'b0: Y <= D0; 1'b1: Y <= D1; endcase end 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, output reg Y ); always @(*) begin case ({S1, S0}) 2'b00: Y <= D0; 2'b01: Y <= D1; 2'b10: Y <= D2; 2'b11: Y <= D3; endcase end 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, output reg Y ); always @(*) begin case ({S2, S1, S0}) 3'b000: Y <= D0; 3'b001: Y <= D1; 3'b010: Y <= D2; 3'b011: Y <= D3; 3'b100: Y <= D4; 3'b101: Y <= D5; 3'b110: Y <= D6; 3'b111: Y <= D7; endcase end 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 (* blackbox *) 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 (* blackbox *) 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 (* blackbox *) module CC_FIFO_40K ( output A_ECC_1B_ERR, output B_ECC_1B_ERR, output A_ECC_2B_ERR, output B_ECC_2B_ERR, // FIFO pop port output [39:0] A_DO, output [39:0] B_DO, (* clkbuf_sink *) input A_CLK, input A_EN, // FIFO push port input [39:0] A_DI, input [39:0] B_DI, input [39:0] A_BM, input [39:0] B_BM, (* clkbuf_sink *) input B_CLK, input B_EN, input B_WE, // FIFO control input F_RST_N, input [12:0] F_ALMOST_FULL_OFFSET, input [12:0] F_ALMOST_EMPTY_OFFSET, // FIFO status signals output F_FULL, output F_EMPTY, output F_ALMOST_FULL, output F_ALMOST_EMPTY, output F_RD_ERROR, output F_WR_ERROR, output [15:0] F_RD_PTR, output [15:0] F_WR_PTR ); // Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED parameter LOC = "UNPLACED"; // Offset configuration parameter [12:0] ALMOST_FULL_OFFSET = 12'b0; parameter [12:0] ALMOST_EMPTY_OFFSET = 12'b0; // Port Widths parameter A_WIDTH = 0; parameter B_WIDTH = 0; // RAM and Write Modes parameter RAM_MODE = "SDP"; // "TPD" or "SDP" parameter FIFO_MODE = "SYNC"; // "ASYNC" or "SYNC" // 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; endmodule