// Copyright (C) 1991-2006 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions
// and other software and tools, and its AMPP partner logic
// functions, and any output files from any of the foregoing
// (including device programming or simulation files), and any
// associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License
// Subscription Agreement, Altera MegaCore Function License
// Agreement, or other applicable license agreement, including,
// without limitation, that your use is for the sole purpose of
// programming logic devices manufactured by Altera and sold by
// Altera or its authorized distributors. Please refer to the
// applicable agreement for further details.
// Quartus II 6.1 Build 201 11/27/2006
///////////////////////////////////////////////////////////////////////////////
//
// FLEX10KE LCELL ATOM
//
// Supports lut_mask, does not support equations.
// Support normal, arithmetic, updown counter and iclrable counter mode.
// parameter output_mode is informational only and has no simulation function.
// No checking is done for validation of parameters passed from top level.
// Input default values are implemented using tri1 and tri0 net.
//
///////////////////////////////////////////////////////////////////////////////
`timescale 1 ps/1 ps
module flex10ke_asynch_lcell (dataa, datab, datac, datad,
cin, cascin, qfbkin,
combout, regin, cout, cascout) ;
parameter operation_mode = "normal" ;
parameter output_mode = "reg_and_comb";
parameter lut_mask = "ffff" ;
parameter cin_used = "false";
input dataa, datab, datac, datad ;
input cin, qfbkin;
input cascin;
output cout, cascout, regin, combout ;
reg icout, data, tmp_cascin;
reg [15:0] bin_mask;
reg [2:0] iop_mode;
wire idataa;
wire idatab;
wire idatac;
wire idatad;
wire icascin;
wire icin;
buf (idataa, dataa);
buf (idatab, datab);
buf (idatac, datac);
buf (idatad, datad);
buf (icascin, cascin);
buf (icin, cin);
specify
(dataa => combout) = (0, 0) ;
(datab => combout) = (0, 0) ;
(datac => combout) = (0, 0) ;
(datad => combout) = (0, 0) ;
(cascin => combout) = (0, 0) ;
(cin => combout) = (0, 0) ;
(qfbkin => combout) = (0, 0) ;
(dataa => cout) = (0, 0);
(datab => cout) = (0, 0);
(datac => cout) = (0, 0);
(datad => cout) = (0, 0);
(cin => cout) = (0, 0) ;
(qfbkin => cout) = (0, 0) ;
(cascin => cascout) = (0, 0) ;
(cin => cascout) = (0, 0) ;
(dataa => cascout) = (0, 0) ;
(datab => cascout) = (0, 0) ;
(datac => cascout) = (0, 0) ;
(datad => cascout) = (0, 0) ;
(qfbkin => cascout) = (0, 0) ;
(dataa => regin) = (0, 0) ;
(datab => regin) = (0, 0) ;
(datac => regin) = (0, 0) ;
(datad => regin) = (0, 0) ;
(cascin => regin) = (0, 0) ;
(cin => regin) = (0, 0) ;
(qfbkin => regin) = (0, 0) ;
endspecify
function [16:1] str_to_bin ;
input [8*4:1] s;
reg [8*4:1] reg_s;
reg [4:1] digit [8:1];
reg [8:1] tmp;
integer m , ivalue ;
begin
ivalue = 0;
reg_s = s;
for (m=1; m<=4; m= m+1 )
begin
tmp = reg_s[32:25];
digit[m] = tmp & 8'b00001111;
reg_s = reg_s << 8;
if (tmp[7] == 'b1)
digit[m] = digit[m] + 9;
end
str_to_bin = {digit[1], digit[2], digit[3], digit[4]};
end
endfunction
function lut4 ;
input [15:0] mask ;
input dataa, datab, datac, datad ;
reg prev_lut4;
reg dataa_new, datab_new, datac_new, datad_new;
integer h, i, j, k;
integer hn, in, jn, kn;
integer exitloop;
integer check_prev;
begin
lut4 = mask[{datad, datac, datab, dataa}]; // Try direct index first
if (lut4 === 1'bx)
begin
if ((datad === 1'bx) || (datad === 1'bz))
begin
datad_new = 1'b0;
hn = 2;
end
else
begin
datad_new = datad;
hn = 1;
end
check_prev = 0;
exitloop = 0;
h = 1;
while ((h <= hn) && (exitloop == 0))
begin
if ((datac === 1'bx) || (datac === 1'bz))
begin
datac_new = 1'b0;
in = 2;
end
else
begin
datac_new = datac;
in = 1;
end
i = 1;
while ((i <= in) && (exitloop ==0))
begin
if ((datab === 1'bx) || (datab === 1'bz))
begin
datab_new = 1'b0;
jn = 2;
end
else
begin
datab_new = datab;
jn = 1;
end
j = 1;
while ((j <= jn) && (exitloop ==0))
begin
if ((dataa === 1'bx) || (dataa === 1'bz))
begin
dataa_new = 1'b0;
kn = 2;
end
else
begin
dataa_new = dataa;
kn = 1;
end
k = 1;
while ((k <= kn) && (exitloop ==0))
begin
lut4 = mask[{datad_new, datac_new, datab_new, dataa_new}];
if ((check_prev == 1) && (prev_lut4 !==lut4))
begin
lut4 = 1'bx;
exitloop = 1;
end
else
begin
check_prev = 1;
prev_lut4 = lut4;
end
k = k + 1;
dataa_new = 1'b1;
end // loop a
j = j + 1;
datab_new = 1'b1;
end // loop b
i = i + 1;
datac_new = 1'b1;
end // loop c
h = h + 1;
datad_new = 1'b1;
end // loop d
end
end
endfunction
initial
begin
tmp_cascin = 1;
bin_mask = str_to_bin (lut_mask) ;
if (operation_mode == "normal" && cin_used == "true") iop_mode = 4; // normal+cin is chain end only
else if (operation_mode == "normal") iop_mode = 0; // most common
else if (operation_mode == "arithmetic") iop_mode = 1; // second most common
else if (operation_mode == "up_dn_cntr") iop_mode = 2;
else if (operation_mode == "clrb_cntr") iop_mode = 3;
else
begin
$display ("Error: Invalid operation_mode specified\n");
iop_mode = 5;
end
end
always @(idatad or idatac or idatab or idataa or icin or
icascin or qfbkin)
begin
if (iop_mode == 0) // operation_mode == "normal" without cin
begin
if ((icascin == 1'b1) || (icascin == 1'b0))
tmp_cascin = icascin;
data = lut4(bin_mask, idataa, idatab, idatac, idatad) && tmp_cascin;
end
else if (iop_mode == 1) // operation_mode == "arithmetic"
begin
if ((icascin == 1'b1) || (icascin == 1'b0))
tmp_cascin = icascin;
data = lut4 (bin_mask, idataa, idatab, icin, 'b1) && tmp_cascin ;
icout = lut4 ( bin_mask, idataa, idatab, icin, 'b0) ;
end
else if (iop_mode == 2) // operation_mode == "up_dn_cntr"
begin
if ((icascin == 1'b1) || (icascin == 1'b0))
tmp_cascin = icascin;
icout = lut4(bin_mask, qfbkin, idatab, icin, 'b0);
if (idatad == 'b0)
data = idatac && tmp_cascin;
else
data = (lut4(bin_mask, idataa, qfbkin, icin, 'b1)) && tmp_cascin;
end
else if (iop_mode == 3) // operation_mode == "clrb_cntr"
begin
icout = lut4(bin_mask, qfbkin, idatab, icin, 'b0);
if (idatad == 'b0)
data = idatac && idatab;
else
data = (lut4(bin_mask, idataa, qfbkin, icin, 'b1)) && idatab;
end
else if (iop_mode == 4) // operation_mode == "normal" with cin
begin
if ((icascin == 1'b1) || (icascin == 1'b0))
tmp_cascin = icascin;
data = lut4 (bin_mask, idataa, idatab, icin, idatad) && tmp_cascin;
end
end
and (cascout, data, 'b1) ;
and (combout, data, 'b1) ;
and (cout, icout, 'b1) ;
and (regin, data, 'b1) ;
endmodule
`timescale 1 ps/1 ps
module flex10ke_lcell_register (clk, aclr, aload,
datain, dataa, datab, datac, datad, devclrn, devpor, regout, qfbko) ;
parameter operation_mode = "normal";
parameter packed_mode = "false" ;
parameter clock_enable_mode = "false";
parameter x_on_violation = "on";
input clk, datain, dataa, datab, datac, datad;
input aclr, aload, devclrn, devpor ;
output regout, qfbko ;
reg iregout, init, oldclk;
reg [1:0] isync_mode;
reg iclock_enable_mode;
wire clk_in, idataa, idatac, idatad;
wire reset;
reg datain_viol, dataa_viol, datab_viol, datac_viol, datad_viol;
reg aload_viol;
reg clk_per_viol;
reg violation;
wire iclr;
wire iaload;
wire idatab;
buf (clk_in, clk);
buf (iclr, aclr);
buf (iaload, aload);
buf (idataa, dataa);
buf (idatab, datab);
buf (idatac, datac);
buf (idatad, datad);
assign reset = devpor && devclrn && (!iclr) && idataa;
specify
$period (posedge clk &&& reset, 0, clk_per_viol);
$setuphold (posedge clk &&& reset, datain, 0, 0, datain_viol) ;
$setuphold (posedge clk &&& reset, dataa, 0, 0, dataa_viol) ;
$setuphold (posedge clk &&& reset, datab, 0, 0, datab_viol) ;
$setuphold (posedge clk &&& reset, datac, 0, 0, datac_viol) ;
$setuphold (posedge clk &&& reset, datad, 0, 0, datad_viol) ;
$setuphold (posedge clk &&& reset, aload, 0, 0, aload_viol) ;
(posedge clk => (regout +: iregout)) = 0 ;
(posedge aclr => (regout +: 1'b0)) = (0, 0) ;
(posedge clk => (qfbko +: iregout)) = 0 ;
(posedge aclr => (qfbko +: 1'b0)) = (0, 0) ;
endspecify
initial
begin
violation = 1;
init = 0;
oldclk = 'b0;
if (operation_mode == "clrb_cntr") isync_mode = 0;
else if (operation_mode == "up_dn_cntr") isync_mode = 1;
else if (packed_mode == "true") isync_mode = 2;
else if (packed_mode == "false") isync_mode = 3;
else
$display("Error: Invalid combination of parameters used. Packed mode may be used only when operation_mode is 'normal'.\n");
iclock_enable_mode = (clock_enable_mode == "true");
end
always @ (datain_viol or dataa_viol or datab_viol or datac_viol or datad_viol or aload_viol or clk_per_viol)
begin
if (x_on_violation == "on")
violation = 1;
end
always @ (clk_in or iclr or devclrn or devpor or posedge violation or idatac or iaload)
begin
if (violation == 1'b1)
begin
violation = 0;
iregout = 'bx;
end
else
begin
if (devclrn == 'b0)
iregout = 'b0;
else if (iclr == 'b1)
iregout = 'b0 ;
else if (iaload == 'b1)
iregout = idatac;
else if ((clk_in == 'b1)&&(oldclk == 'b0)&&((iclock_enable_mode == 1'b0) || (idataa == 1'b1)))
begin
case (isync_mode)
0: // operation_mode == "clrb_cntr"
begin
if (idatab == 'b0)
begin
iregout = 'b0;
end
else if (idatad == 'b0)
begin
iregout = idatac;
end
else
begin
iregout = datain;
end
end
1: // operation_mode == "up_dn_cntr"
begin
if (idatad == 'b0)
begin
iregout = idatac;
end
else
begin
iregout = datain;
end
end
2: iregout = idatad; // packed_mode == "true"
3: iregout = datain; // packed_mode == "false"
endcase
end
end
if (init==0)
begin
iregout = 'b0;
init = 1;
end
oldclk = clk_in;
end
and (regout, iregout, 'b1) ;
and (qfbko, iregout, 'b1) ;
endmodule
`timescale 1 ps/1 ps
module flex10ke_lcell (clk, dataa, datab, datac, datad, aclr,
aload, cin, cascin, devclrn, devpor,
combout, regout, cout, cascout) ;
parameter operation_mode = "normal" ;
parameter output_mode = "reg_and_comb";
parameter packed_mode = "false" ;
parameter clock_enable_mode = "false";
parameter lut_mask = "ffff" ;
parameter cin_used = "false";
parameter x_on_violation = "on";
input clk, dataa, datab, datac, datad ;
input aclr, aload, cin, cascin, devclrn, devpor ;
output cout, cascout, regout, combout ;
wire dffin, qfbk;
flex10ke_asynch_lcell lecomb (dataa, datab, datac, datad, cin, cascin,
qfbk, combout, dffin, cout, cascout);
defparam lecomb.operation_mode = operation_mode,
lecomb.output_mode = output_mode,
lecomb.cin_used = cin_used,
lecomb.lut_mask = lut_mask;
flex10ke_lcell_register lereg (clk, aclr, aload, dffin, dataa, datab, datac, datad,
devclrn, devpor, regout, qfbk);
defparam lereg.operation_mode = operation_mode,
lereg.packed_mode = packed_mode,
lereg.clock_enable_mode = clock_enable_mode,
lereg.x_on_violation = x_on_violation;
endmodule
///////////////////////////////////////////////////////////////////////////////
//
// FLEX10KE IO Atom
//
`timescale 1 ps/1 ps
module flex10ke_io (clk, datain, aclr, ena, oe, devclrn, devoe, devpor,
padio, dataout) ;
parameter operation_mode = "input" ;
parameter reg_source_mode = "none" ;
parameter feedback_mode = "from_pin" ;
parameter power_up = "low";
parameter open_drain_output = "false";
inout padio ;
input datain, clk, aclr, ena, oe, devpor, devoe, devclrn ;
output dataout;
wire reg_pre, reg_clr;
tri1 ena;
tri0 aclr;
wire dffeD, dffeQ;
specify
endspecify
assign reg_clr = (power_up == "low") ? devpor : 1'b1;
assign reg_pre = (power_up == "high") ? devpor : 1'b1;
flex10ke_asynch_io inst1 (datain, oe, padio, dffeD, dffeQ, dataout);
defparam
inst1.operation_mode = operation_mode,
inst1.reg_source_mode = reg_source_mode,
inst1.feedback_mode = feedback_mode,
inst1.open_drain_output = open_drain_output;
dffe_io io_reg (dffeQ, clk, ena, dffeD, devclrn && !aclr && reg_clr, reg_pre);
endmodule
//
// ASYNCH_IO
//
module flex10ke_asynch_io(datain, oe, padio, dffeD, dffeQ, dataout);
parameter operation_mode = "input" ;
parameter reg_source_mode = "none" ;
parameter feedback_mode = "from_pin" ;
parameter open_drain_output = "false";
input datain, oe;
input dffeQ;
output dffeD;
output dataout;
inout padio;
reg tmp_comb, tri_in, tri_in_new, temp;
reg reg_indata, tmp_dataout, switch;
reg [3:0] isource_mode;
reg op_mode_output;
reg op_mode_bidir;
reg ifeedback_from_pin;
reg ifeedback_from_reg;
wire regout;
specify
(padio => dataout) = (0, 0);
(posedge oe => (padio +: tri_in_new)) = 0;
(negedge oe => (padio +: 1'bz)) = 0;
(datain => padio) = (0, 0);
(dffeQ => padio) = (0, 0);
(dffeQ => dataout) = (0, 0);
endspecify
wire ipadio;
wire idatain;
wire ioe;
buf (ipadio, padio);
buf (idatain, datain);
buf (ioe, oe);
initial
begin
tri_in = 1'b0;
tmp_comb = 'b0;
reg_indata = 'b0;
if ((reg_source_mode == "none") && (feedback_mode == "none"))
begin
if ((operation_mode == "output") ||
(operation_mode == "bidir"))
isource_mode = 0; // tri_in = idatain;
end
else if ((reg_source_mode == "none") && (feedback_mode == "from_pin"))
begin
if (operation_mode == "input")
isource_mode = 1; // tmp_comb = ipadio;
else if (operation_mode == "bidir")
begin
isource_mode = 2; // tmp_comb = ipadio; tri_in = idatain;
end
else $display ("Error: Invalid operation_mode specified\n");
end
else if ((reg_source_mode == "data_in") && (feedback_mode == "from_reg"))
begin
if ((operation_mode == "output") || (operation_mode == "bidir"))
begin
isource_mode = 3; // tri_in = idatain; reg_indata = idatain;
end
else $display ("Error: Invalid operation_mode specified\n");
end
else if ((reg_source_mode == "pin_only") &&
(feedback_mode == "from_reg"))
begin
if (operation_mode == "input")
isource_mode = 4; // reg_indata = ipadio;
else if (operation_mode == "bidir")
begin
isource_mode = 5; // tri_in = idatain; reg_indata = ipadio;
end
else $display ("Error: Invalid operation_mode specified\n");
end
else if ((reg_source_mode == "data_in_to_pin") &&
(feedback_mode == "from_pin"))
begin
if (operation_mode == "bidir")
begin
isource_mode = 6; // tri_in = dffeQ; reg_indata = idatain; tmp_comb = ipadio;
end
else $display ("Error: Invalid operation_mode specified\n");
end
else if ((reg_source_mode == "data_in_to_pin") &&
(feedback_mode == "from_reg"))
begin
if ((operation_mode == "output") ||
(operation_mode == "bidir"))
begin
isource_mode = 7; // reg_indata = idatain; tri_in = dffeQ;
end
else $display ("Error: Invalid operation_mode specified\n");
end
else if ((reg_source_mode == "data_in_to_pin") &&
(feedback_mode == "none"))
begin
if ((operation_mode == "output") ||
(operation_mode == "bidir"))
begin
isource_mode = 8; // tri_in = dffeQ; reg_indata = idatain;
end
else $display ("Error: Invalid operation_mode specified\n");
end
else if ((reg_source_mode == "pin_loop") &&
(feedback_mode == "from_pin"))
begin
if (operation_mode == "bidir")
begin
isource_mode = 9; // tri_in = dffeQ; reg_indata = ipadio; tmp_comb = ipadio;
end
else $display ("Error: Invalid operation_mtmp_dataouttmp_dataoutode specified\n");
end
else if ((reg_source_mode == "pin_loop") &&
(feedback_mode == "from_reg"))
begin
if (operation_mode == "bidir")
begin
isource_mode = 10; // reg_indata = ipadio; tri_in = dffeQ;
end
else $display ("Error: Invalid operation_mode specified\n");
end
else
begin
isource_mode = 11;
$display ("Error: Invalid combination of paratmp_dataoutmeters used\n");
end
op_mode_output = (operation_mode == "output");
op_mode_bidir = (operation_mode == "bidir");
ifeedback_from_pin = (feedback_mode == "from_pin");
ifeedback_from_reg = (feedback_mode == "from_reg");
end
always @(ipadio or idatain or ioe or dffeQ)
begin
case (isource_mode)
0: tri_in = idatain;
1: tmp_comb = ipadio;
2: begin
tmp_comb = ipadio;
tri_in = idatain;
end
3: begin
tri_in = idatain;
reg_indata = idatain;
end
4: reg_indata = ipadio;
5: begin
tri_in = idatain;
reg_indata = ipadio;
end
6: begin
tri_in = dffeQ;
reg_indata = idatain;
tmp_comb = ipadio;
end
7: begin
reg_indata = idatain;
tri_in = dffeQ;
end
8: begin
tri_in = dffeQ;
reg_indata = idatain;
end
9: begin
tri_in = dffeQ;
reg_indata = ipadio;
tmp_comb = ipadio;
end
10: begin
reg_indata = ipadio;
tri_in = dffeQ;
end
endcase
if (op_mode_output)
begin
if (ioe == 'b0)
temp = 'bz;
else
temp = tri_in;
if (open_drain_output == "false")
tri_in_new = temp;
else if (open_drain_output == "true")
begin
if ((reg_source_mode == "data_in_to_pin") && (feedback_mode != "from_pin"))
begin
if (temp == 'b0)
tri_in_new = 'b0;
else
tri_in_new = 'bz;
end
else
begin
if (idatain == 'b1)
tri_in_new = 'bz;
else
tri_in_new = 'b0;
end
end
end
else if (op_mode_bidir && (ioe == 'b1))
begin
if (open_drain_output == "false")
tri_in_new = tri_in;
else if (open_drain_output == "true")
begin
if (tri_in == 'b0)
tri_in_new = 'b0;
else
tri_in_new = 'bz;
end
end
else
tri_in_new = 'bz;
if (ifeedback_from_pin)
begin
tmp_dataout = tmp_comb;
switch = 'b0;
end
else if (ifeedback_from_reg)
begin
tmp_dataout = 'b0;
if (reg_indata == 'bx)
switch = 'b0;
else
switch = 'b1;
end
end
and (dffeD, reg_indata, 1'b1);
and (regout, dffeQ, switch, 1'b1);
or (dataout, regout, tmp_dataout, 1'b0);
pmos (padio, tri_in_new, 'b0);
endmodule
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : FLEX10KE_ASYNCH_MEM
//
// Description : Timing simulation model for the asynchronous RAM array
//
//////////////////////////////////////////////////////////////////////////////
`timescale 1 ps/1 ps
module flex10ke_asynch_mem (datain,
we,
re,
raddr,
waddr,
modesel,
dataout);
// INPUT PORTS
input datain;
input we;
input re;
input [10:0] raddr;
input [10:0] waddr;
input [15:0] modesel;
// OUTPUT PORTS
output dataout;
// GLOBAL PARAMETERS
parameter logical_ram_depth = 2048;
parameter infile = "none";
parameter address_width = 11;
parameter first_address = 0;
parameter last_address = 2047;
parameter mem1 = 512'b0;
parameter mem2 = 512'b0;
parameter mem3 = 512'b0;
parameter mem4 = 512'b0;
parameter bit_number = 0;
parameter write_logic_clock = "none";
parameter read_enable_clock = "none";
parameter data_out_clock = "none";
parameter operation_mode = "single_port";
// INTERNAL VARIABLES AND NETS
reg tmp_dataout;
reg [10:0] rword;
reg [10:0] wword;
reg [2047:0] mem;
reg write_en;
reg read_en;
reg write_en_last_value;
wire [10:0] waddr_in;
wire [10:0] raddr_in;
integer i;
wire we_in;
wire re_in;
wire datain_in;
// BUFFER INPUTS
buf (we_in, we);
buf (re_in, re);
buf (datain_in, datain);
buf (waddr_in[0], waddr[0]);
buf (waddr_in[1], waddr[1]);
buf (waddr_in[2], waddr[2]);
buf (waddr_in[3], waddr[3]);
buf (waddr_in[4], waddr[4]);
buf (waddr_in[5], waddr[5]);
buf (waddr_in[6], waddr[6]);
buf (waddr_in[7], waddr[7]);
buf (waddr_in[8], waddr[8]);
buf (waddr_in[9], waddr[9]);
buf (waddr_in[10], waddr[10]);
buf (raddr_in[0], raddr[0]);
buf (raddr_in[1], raddr[1]);
buf (raddr_in[2], raddr[2]);
buf (raddr_in[3], raddr[3]);
buf (raddr_in[4], raddr[4]);
buf (raddr_in[5], raddr[5]);
buf (raddr_in[6], raddr[6]);
buf (raddr_in[7], raddr[7]);
buf (raddr_in[8], raddr[8]);
buf (raddr_in[9], raddr[9]);
buf (raddr_in[10], raddr[10]);
// TIMING PATHS
specify
$setup (waddr[0], posedge we &&& (~modesel[2]), 0);
$setup (waddr[1], posedge we &&& (~modesel[2]), 0);
$setup (waddr[2], posedge we &&& (~modesel[2]), 0);
$setup (waddr[3], posedge we &&& (~modesel[2]), 0);
$setup (waddr[4], posedge we &&& (~modesel[2]), 0);
$setup (waddr[5], posedge we &&& (~modesel[2]), 0);
$setup (waddr[6], posedge we &&& (~modesel[2]), 0);
$setup (waddr[7], posedge we &&& (~modesel[2]), 0);
$setup (waddr[8], posedge we &&& (~modesel[2]), 0);
$setup (waddr[9], posedge we &&& (~modesel[2]), 0);
$setup (waddr[10], posedge we &&& (~modesel[2]), 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[0], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[1], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[2], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[3], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[4], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[5], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[6], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[7], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[8], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[9], 0, 0);
$setuphold (negedge re &&& (~modesel[4]), raddr[10], 0, 0);
$setuphold (negedge we &&& (~modesel[0]), datain, 0, 0);
$hold (negedge we &&& (~modesel[2]), waddr[0], 0);
$hold (negedge we &&& (~modesel[2]), waddr[1], 0);
$hold (negedge we &&& (~modesel[2]), waddr[2], 0);
$hold (negedge we &&& (~modesel[2]), waddr[3], 0);
$hold (negedge we &&& (~modesel[2]), waddr[4], 0);
$hold (negedge we &&& (~modesel[2]), waddr[5], 0);
$hold (negedge we &&& (~modesel[2]), waddr[6], 0);
$hold (negedge we &&& (~modesel[2]), waddr[7], 0);
$hold (negedge we &&& (~modesel[2]), waddr[8], 0);
$hold (negedge we &&& (~modesel[2]), waddr[9], 0);
$hold (negedge we &&& (~modesel[2]), waddr[10], 0);
$nochange (posedge we &&& (~modesel[2]), waddr, 0, 0);
$width (posedge we, 0);
$width (posedge re, 0);
(raddr[0] => dataout) = (0, 0);
(raddr[1] => dataout) = (0, 0);
(raddr[2] => dataout) = (0, 0);
(raddr[3] => dataout) = (0, 0);
(raddr[4] => dataout) = (0, 0);
(raddr[5] => dataout) = (0, 0);
(raddr[6] => dataout) = (0, 0);
(raddr[7] => dataout) = (0, 0);
(raddr[8] => dataout) = (0, 0);
(raddr[9] => dataout) = (0, 0);
(raddr[10] => dataout) = (0, 0);
(waddr[0] => dataout) = (0, 0);
(waddr[1] => dataout) = (0, 0);
(waddr[2] => dataout) = (0, 0);
(waddr[3] => dataout) = (0, 0);
(waddr[4] => dataout) = (0, 0);
(waddr[5] => dataout) = (0, 0);
(waddr[6] => dataout) = (0, 0);
(waddr[7] => dataout) = (0, 0);
(waddr[8] => dataout) = (0, 0);
(waddr[9] => dataout) = (0, 0);
(waddr[10] => dataout) = (0, 0);
(re => dataout) = (0, 0);
(we => dataout) = (0, 0);
(datain => dataout) = (0, 0);
endspecify
initial
begin
mem = {mem4, mem3, mem2, mem1};
// if WE is not registered, initial RAM content is X
// note that if WE is not registered, the MIF file cannot be used
if ((operation_mode != "rom") && (write_logic_clock == "none"))
begin
for (i = 0; i <= 2047; i=i+1)
mem[i] = 'bx;
end
tmp_dataout = 'b0;
if ((operation_mode == "rom") || (operation_mode == "single_port"))
begin
// re is always active
tmp_dataout = mem[0];
end
else begin
// re is inactive
tmp_dataout = 'b0;
end
if (read_enable_clock != "none")
begin
if ((operation_mode == "rom") || (operation_mode == "single_port"))
begin
// re is always active
tmp_dataout = mem[0];
end
else begin
// eab cell output powers up to VCC
tmp_dataout = 'b1;
end
end
end
always @(we_in or re_in or raddr_in or waddr_in or datain_in)
begin
rword = raddr_in[10:0];
wword = waddr_in[10:0];
read_en = re_in;
write_en = we_in;
if (modesel[14:13] == 2'b10)
begin
if (read_en == 1)
tmp_dataout = mem[rword];
end
else if (modesel[14:13] == 2'b00)
begin
if ((write_en == 0) && (write_en_last_value == 1))
mem[wword] = datain_in;
if (write_en == 0)
tmp_dataout = mem[wword];
else if (write_en == 1)
tmp_dataout = datain_in;
else tmp_dataout = 'bx;
end
else if (modesel[14:13] == 2'b01)
begin
if ((write_en == 0) && (write_en_last_value == 1))
mem[wword] = datain_in;
if ((read_en == 1) && (rword == wword) && (write_en == 1))
tmp_dataout = datain_in;
else if (read_en == 1)
tmp_dataout = mem[rword];
end
write_en_last_value = write_en;
end
and (dataout, tmp_dataout, 'b1);
endmodule // flex10ke_asynch_mem
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : PRIM_DFFE
//
// Description : State table for UDP PRIM_DFFE
//
//////////////////////////////////////////////////////////////////////////////
primitive PRIM_DFFE (Q, ENA, D, CLK, CLRN, PRN, notifier);
input D;
input CLRN;
input PRN;
input CLK;
input ENA;
input notifier;
output Q; reg Q;
initial Q = 1'b0;
table
// ENA D CLK CLRN PRN notifier : Qt : Qt+1
(??) ? ? 1 1 ? : ? : -; // pessimism
x ? ? 1 1 ? : ? : -; // pessimism
1 1 (01) 1 1 ? : ? : 1; // clocked data
1 1 (01) 1 x ? : ? : 1; // pessimism
1 1 ? 1 x ? : 1 : 1; // pessimism
1 0 0 1 x ? : 1 : 1; // pessimism
1 0 x 1 (?x) ? : 1 : 1; // pessimism
1 0 1 1 (?x) ? : 1 : 1; // pessimism
1 x 0 1 x ? : 1 : 1; // pessimism
1 x x 1 (?x) ? : 1 : 1; // pessimism
1 x 1 1 (?x) ? : 1 : 1; // pessimism
1 0 (01) 1 1 ? : ? : 0; // clocked data
1 0 (01) x 1 ? : ? : 0; // pessimism
1 0 ? x 1 ? : 0 : 0; // pessimism
0 ? ? x 1 ? : ? : -;
1 1 0 x 1 ? : 0 : 0; // pessimism
1 1 x (?x) 1 ? : 0 : 0; // pessimism
1 1 1 (?x) 1 ? : 0 : 0; // pessimism
1 x 0 x 1 ? : 0 : 0; // pessimism
1 x x (?x) 1 ? : 0 : 0; // pessimism
1 x 1 (?x) 1 ? : 0 : 0; // pessimism
1 1 (x1) 1 1 ? : 1 : 1; // reducing pessimism
1 0 (x1) 1 1 ? : 0 : 0;
1 1 (0x) 1 1 ? : 1 : 1;
1 0 (0x) 1 1 ? : 0 : 0;
? ? ? 0 1 ? : ? : 0; // asynch clear
? ? ? 1 0 ? : ? : 1; // asynch set
1 ? (?0) 1 1 ? : ? : -; // ignore falling clock
1 ? (1x) 1 1 ? : ? : -; // ignore falling clock
1 * ? ? ? ? : ? : -; // ignore data edges
1 ? ? (?1) ? ? : ? : -; // ignore edges on
1 ? ? ? (?1) ? : ? : -; // set and clear
0 ? ? 1 1 ? : ? : -; // set and clear
? ? ? 1 1 * : ? : x; // spr 36954 - at any
// notifier event,
// output 'x'
endtable
endprimitive // PRIM_DFFE
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : FLEX10KE_DFFE
//
// Description : Timing simulation model for a DFFE register
//
//////////////////////////////////////////////////////////////////////////////
module flex10ke_dffe ( Q,
CLK,
ENA,
D,
CLRN,
PRN );
// INPUT PORTS
input D;
input CLK;
input CLRN;
input PRN;
input ENA;
// OUTPUT PORTS
output Q;
// INTERNAL VARIABLES AND NETS
wire legal;
reg viol_notifier;
// INSTANTIATE THE UDP
PRIM_DFFE ( Q, ENA, D, CLK, CLRN, PRN, viol_notifier );
// filter out illegal values like 'X'
and(legal, ENA, CLRN, PRN);
specify
specparam TREG = 0;
specparam TREN = 0;
specparam TRSU = 0;
specparam TRH = 0;
specparam TRPR = 0;
specparam TRCL = 0;
$setup ( D, posedge CLK &&& legal, TRSU, viol_notifier ) ;
$hold ( posedge CLK &&& legal, D, TRH, viol_notifier ) ;
$setup ( ENA, posedge CLK &&& legal, TREN, viol_notifier ) ;
$hold ( posedge CLK &&& legal, ENA, 0, viol_notifier ) ;
( negedge CLRN => (Q +: 1'b0)) = ( TRCL, TRCL) ;
( negedge PRN => (Q +: 1'b1)) = ( TRPR, TRPR) ;
( posedge CLK => (Q +: D)) = ( TREG, TREG) ;
endspecify
endmodule // flex10ke_dffe
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : DFFE_IO
//
// Description : Timing simulation model for a DFFE register for IO atom
//
//////////////////////////////////////////////////////////////////////////////
module dffe_io ( Q, CLK, ENA, D, CLRN, PRN );
input D;
input CLK;
input CLRN;
input PRN;
input ENA;
output Q;
wire D_ipd;
wire ENA_ipd;
wire CLK_ipd;
wire PRN_ipd;
wire CLRN_ipd;
buf (D_ipd, D);
buf (ENA_ipd, ENA);
buf (CLK_ipd, CLK);
buf (PRN_ipd, PRN);
buf (CLRN_ipd, CLRN);
wire legal;
reg viol_notifier;
PRIM_DFFE ( Q, ENA_ipd, D_ipd, CLK_ipd, CLRN_ipd, PRN_ipd, viol_notifier);
and(legal, ENA_ipd, CLRN_ipd, PRN_ipd);
specify
specparam TREG = 0;
specparam TREN = 0;
specparam TRSU = 0;
specparam TRH = 0;
specparam TRPR = 0;
specparam TRCL = 0;
$setup ( D, posedge CLK &&& legal, TRSU, viol_notifier ) ;
$hold ( posedge CLK &&& legal, D, TRH, viol_notifier ) ;
$setup ( ENA, posedge CLK &&& legal, TREN, viol_notifier ) ;
$hold ( posedge CLK &&& legal, ENA, 0, viol_notifier ) ;
( negedge CLRN => (Q +: 1'b0)) = ( TRCL, TRCL) ;
( negedge PRN => (Q +: 1'b1)) = ( TRPR, TRPR) ;
( posedge CLK => (Q +: D)) = ( TREG, TREG) ;
endspecify
endmodule // dffe_io
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : mux21
//
// Description : Simulation model for a 2 to 1 mux used in the RAM_SLICE
// This is a purely functional module, without any timing.
//
//////////////////////////////////////////////////////////////////////////////
module mux21 (MO,
A,
B,
S);
input A, B, S;
output MO;
assign MO = (S == 1) ? B : A;
endmodule // mux21
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : and1
//
// Description : Simulation model for a 1-input AND gate
//
//////////////////////////////////////////////////////////////////////////////
module and1 (Y,
IN1);
input IN1;
output Y;
specify
(IN1 => Y) = (0, 0);
endspecify
buf (Y, IN1);
endmodule // and1
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : and11
//
// Description : Simulation model for a 11-input AND gate
//
//////////////////////////////////////////////////////////////////////////////
module and11 (Y, IN1);
input [10:0] IN1;
output [10:0] Y;
specify
(IN1 => Y) = (0, 0);
endspecify
buf (Y[0], IN1[0]);
buf (Y[1], IN1[1]);
buf (Y[2], IN1[2]);
buf (Y[3], IN1[3]);
buf (Y[4], IN1[4]);
buf (Y[5], IN1[5]);
buf (Y[6], IN1[6]);
buf (Y[7], IN1[7]);
buf (Y[8], IN1[8]);
buf (Y[9], IN1[9]);
buf (Y[10], IN1[10]);
endmodule // and11
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : nmux21
//
// Description : Simulation model for a 2 to 1 mux used in the RAM_SLICE
// The output is an inversion of the selected input.
// This is a purely functional module, without any timing.
//
//////////////////////////////////////////////////////////////////////////////
module nmux21 (MO,
A,
B,
S);
input A, B, S;
output MO;
assign MO = (S == 1) ? ~B : ~A;
endmodule // nmux21
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : bmux21
//
// Description : Simulation model for a 2 to 1 mux used in the RAM_SLICE
// Each input is a 16-bit bus.
// This is a purely functional module, without any timing.
//
//////////////////////////////////////////////////////////////////////////////
module bmux21 (MO,
A,
B,
S);
input [10:0] A, B;
input S;
output [10:0] MO;
assign MO = (S == 1) ? B : A;
endmodule // bmux21
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : b5mux21
//
// Description : Simulation model for a 2 to 1 mux used in the CAM_SLICE.
// Each input is a 5-bit bus.
// This is a purely functional module, without any timing.
//
//////////////////////////////////////////////////////////////////////////////
module b5mux21 (MO,
A,
B,
S);
input [4:0] A, B;
input S;
output [4:0] MO;
assign MO = (S == 1) ? B : A;
endmodule // b5mux21
//////////////////////////////////////////////////////////////////////////////
//
// Module Name : FLEX10KE_RAM_SLICE
//
// Description : Timing simulation model for a single RAM segment of the
// FLEX10KE family.
// This model is a top-level structural description of the
// RAM segment. It instantiates the peripheral registers,
// mode-control multiplexers and the asynchronous memory
// array.
//
//////////////////////////////////////////////////////////////////////////////
module flex10ke_ram_slice (datain,
clr0,
clk0,
clk1,
ena0,
ena1,
we,
re,
waddr,
raddr,
devclrn,
devpor,
modesel,
dataout
);
// INPUT PORTS
input datain;
input clk0;
input clk1;
input clr0;
input ena0;
input ena1;
input we;
input re;
input devclrn;
input devpor;
input [10:0] raddr;
input [10:0] waddr;
input [15:0] modesel;
// OUTPUT PORTS
output dataout;
// GLOBAL PARAMETERS
parameter operation_mode = "single_port";
parameter logical_ram_name = "ram_xxx";
parameter logical_ram_depth = "2k";
parameter logical_ram_width = "1";
parameter address_width = 11;
parameter data_in_clock = "none";
parameter data_in_clear = "none";
parameter write_logic_clock = "none";
parameter write_address_clear = "none";
parameter write_enable_clear = "none";
parameter read_enable_clock = "none";
parameter read_enable_clear = "none";
parameter read_address_clock = "none";
parameter read_address_clear = "none";
parameter data_out_clock = "none";
parameter data_out_clear = "none";
parameter init_file = "none";
parameter first_address = 0;
parameter last_address = 2047;
parameter bit_number = "1";
parameter mem1 = 512'b0;
parameter mem2 = 512'b0;
parameter mem3 = 512'b0;
parameter mem4 = 512'b0;
// INTERNAL NETS AND VARIABLES
wire datain_reg, we_reg, re_reg, dataout_reg;
wire we_reg_mux, we_reg_mux_delayed;
wire [10:0] raddr_reg, waddr_reg;
wire datain_int, we_int, re_int, dataout_int, dataout_tmp;
wire [10:0] raddr_int, waddr_int;
wire reen, raddren, dataouten;
wire datain_clr;
wire re_clk, raddr_clk;
wire datain_reg_sel, write_reg_sel, raddr_reg_sel;
wire re_reg_sel, dataout_reg_sel, re_clk_sel, re_en_sel;
wire raddr_clk_sel, raddr_en_sel;
wire dataout_en_sel;
wire datain_reg_clr, waddr_reg_clr, raddr_reg_clr;
wire re_reg_clr, dataout_reg_clr, we_reg_clr;
wire datain_reg_clr_sel;
wire waddr_reg_clr_sel;
wire we_reg_clr_sel;
wire raddr_reg_clr_sel;
wire re_reg_clr_sel, dataout_reg_clr_sel, NC;
wire we_pulse;
wire clk0_delayed;
reg we_int_delayed, datain_int_delayed;
reg [10:0] waddr_int_delayed;
// PULL UPs
tri1 iena0;
tri1 iena1;
// READ MODESEL PORT BITS
assign datain_reg_sel = modesel[0];
assign datain_reg_clr_sel = modesel[1];
assign write_reg_sel = modesel[2];
assign waddr_reg_clr_sel = modesel[15];
assign we_reg_clr_sel = modesel[3];
assign raddr_reg_sel = modesel[4];
assign raddr_reg_clr_sel = modesel[5];
assign re_reg_sel = modesel[6];
assign re_reg_clr_sel = modesel[7];
assign dataout_reg_sel = modesel[8];
assign dataout_reg_clr_sel = modesel[9];
assign re_clk_sel = modesel[10];
assign re_en_sel = modesel[10];
assign raddr_clk_sel = modesel[11];
assign raddr_en_sel = modesel[11];
assign dataout_en_sel = modesel[12];
assign iena0 = ena0;
assign iena1 = ena1;
assign NC = 0;
always @ (datain_int or waddr_int or we_int)
begin
we_int_delayed = we_int;
waddr_int_delayed <= waddr_int;
datain_int_delayed <= datain_int;
end
mux21 datainsel (datain_int,
datain,
datain_reg,
datain_reg_sel
);
nmux21 datainregclr (datain_reg_clr,
NC,
clr0,
datain_reg_clr_sel
);
bmux21 waddrsel (waddr_int,
waddr,
waddr_reg,
write_reg_sel
);
nmux21 waddrregclr (waddr_reg_clr,
NC,
clr0,
waddr_reg_clr_sel
);
nmux21 weregclr (we_reg_clr,
NC,
clr0,
we_reg_clr_sel
);
mux21 wesel2 (we_int,
we_reg_mux_delayed,
we_pulse,
write_reg_sel
);
mux21 wesel1 (we_reg_mux,
we,
we_reg,
write_reg_sel
);
bmux21 raddrsel (raddr_int,
raddr,
raddr_reg,
raddr_reg_sel
);
nmux21 raddrregclr (raddr_reg_clr,
NC,
clr0,
raddr_reg_clr_sel
);
mux21 resel (re_int,
re,
re_reg,
re_reg_sel
);
mux21 dataoutsel (dataout_tmp,
dataout_int,
dataout_reg,
dataout_reg_sel
);
nmux21 dataoutregclr (dataout_reg_clr,
NC,
clr0,
dataout_reg_clr_sel
);
mux21 raddrclksel (raddr_clk,
clk0,
clk1,
raddr_clk_sel
);
mux21 raddrensel (raddren,
iena0,
iena1,
raddr_en_sel
);
mux21 reclksel (re_clk,
clk0,
clk1,
re_clk_sel
);
mux21 reensel (reen,
iena0,
iena1,
re_en_sel
);
nmux21 reregclr (re_reg_clr,
NC,
clr0,
re_reg_clr_sel
);
mux21 dataoutensel (dataouten,
NC,
iena1,
dataout_en_sel
);
flex10ke_dffe dinreg (datain_reg,
clk0,
iena0,
datain,
datain_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe wereg (we_reg,
clk0,
iena0,
we,
we_reg_clr && devclrn && devpor,
1'b1
);
// clk0 for we_pulse should have same delay as clk of wereg
and1 clk0weregdelaybuf (clk0_delayed,
clk0
);
assign we_pulse = we_reg_mux_delayed && (~clk0_delayed);
and1 wedelaybuf (we_reg_mux_delayed,
we_reg_mux
);
flex10ke_dffe rereg (re_reg,
re_clk,
reen,
re,
re_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe dataoutreg (dataout_reg,
clk1,
dataouten,
dataout_int,
dataout_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_0 (waddr_reg[0],
clk0,
iena0,
waddr[0],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_1 (waddr_reg[1],
clk0,
iena0,
waddr[1],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_2 (waddr_reg[2],
clk0,
iena0,
waddr[2],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_3 (waddr_reg[3],
clk0,
iena0,
waddr[3],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_4 (waddr_reg[4],
clk0,
iena0,
waddr[4],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_5 (waddr_reg[5],
clk0,
iena0,
waddr[5],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_6 (waddr_reg[6],
clk0,
iena0,
waddr[6],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_7 (waddr_reg[7],
clk0,
iena0,
waddr[7],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_8 (waddr_reg[8],
clk0,
iena0,
waddr[8],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_9 (waddr_reg[9],
clk0,
iena0,
waddr[9],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe waddrreg_10 (waddr_reg[10],
clk0,
iena0,
waddr[10],
waddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_0 (raddr_reg[0],
raddr_clk,
raddren,
raddr[0],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_1 (raddr_reg[1],
raddr_clk,
raddren,
raddr[1],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_2 (raddr_reg[2],
raddr_clk,
raddren,
raddr[2],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_3 (raddr_reg[3],
raddr_clk,
raddren,
raddr[3],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_4 (raddr_reg[4],
raddr_clk,
raddren,
raddr[4],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_5 (raddr_reg[5],
raddr_clk,
raddren,
raddr[5],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_6 (raddr_reg[6],
raddr_clk,
raddren,
raddr[6],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_7 (raddr_reg[7],
raddr_clk,
raddren,
raddr[7],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_8 (raddr_reg[8],
raddr_clk,
raddren,
raddr[8],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_9 (raddr_reg[9],
raddr_clk,
raddren,
raddr[9],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_dffe raddrreg_10 (raddr_reg[10],
raddr_clk,
raddren,
raddr[10],
raddr_reg_clr && devclrn && devpor,
1'b1
);
flex10ke_asynch_mem flexmem (datain_int_delayed,
we_int_delayed,
re_int,
raddr_int,
waddr_int_delayed,
modesel,
dataout_int
);
defparam
flexmem.address_width = address_width,
flexmem.bit_number = bit_number,
flexmem.logical_ram_depth = logical_ram_depth,
flexmem.first_address = first_address,
flexmem.last_address = last_address,
flexmem.write_logic_clock = write_logic_clock,
flexmem.read_enable_clock = read_enable_clock,
flexmem.data_out_clock = data_out_clock,
flexmem.infile = init_file,
flexmem.operation_mode = operation_mode,
flexmem.mem1 = mem1,
flexmem.mem2 = mem2,
flexmem.mem3 = mem3,
flexmem.mem4 = mem4;
assign dataout = dataout_tmp;
endmodule // flex10ke_ram_slice
/////////////////////////////////////////////////////////////////////////////
//
// Module Name : FLEX10KE_PLL
//
// Description : Simulation model for the FLEX10KE device family PLL.
//
/////////////////////////////////////////////////////////////////////////////
`timescale 1 ns / 1 ps
module flex10ke_pll (clk,
clk0,
clk1,
locked
);
// INPUT PORTS
input clk;
// OUTPUT PORTS
output clk0;
output clk1;
output locked;
// GLOBAL PARAMETERS
parameter clk0_multiply_by = 1;
parameter clk1_multiply_by = 1;
parameter input_frequency = 1000;
// INTERNAL VARIABLES AND NETS
reg start_inclk;
reg new_inclk0;
reg new_inclk1;
reg pll_lock;
reg clkout0_tmp;
reg clkout1_tmp;
reg locked_tmp;
real pll_last_rising_edge;
real pll_last_falling_edge;
real actual_clk_cycle;
real expected_clk_cycle;
real pll_duty_cycle;
real pll1_half_period;
real pll2_half_period;
integer pll_rising_edge_count;
integer clk0_count;
integer clk1_count;
integer i;
integer j;
specify
endspecify
initial
begin
clk0_count = -1;
clk1_count = -1;
pll_rising_edge_count = 0;
pll_lock = 1;
clkout0_tmp = 1'b0;
clkout1_tmp = 1'b0;
locked_tmp = 1'b0;
// resolve the parameters
if (clk0_multiply_by > clk1_multiply_by)
$display("");
end
always @(posedge clk)
begin
if (pll_rising_edge_count == 0) // this is first rising edge
start_inclk = clk;
else if (pll_rising_edge_count == 1) // this is second rising edge
begin
expected_clk_cycle = input_frequency / 1000.0; // convert to ns
actual_clk_cycle = $realtime - pll_last_rising_edge;
if (actual_clk_cycle < (expected_clk_cycle - 1.0) ||
actual_clk_cycle > (expected_clk_cycle + 1.0))
begin
$display($realtime, "Warning: Input frequency Violation");
pll_lock = 0;
locked_tmp = 0;
end
if ( ($realtime - pll_last_falling_edge) < (pll_duty_cycle - 0.1) || ($realtime - pll_last_falling_edge) > (pll_duty_cycle + 0.1) )
begin
$display($realtime, "Warning: Duty Cycle Violation");
pll_lock = 0;
locked_tmp = 0;
end
end
else if ( ($realtime - pll_last_rising_edge) < (actual_clk_cycle - 0.1) ||
($realtime - pll_last_rising_edge) > (actual_clk_cycle + 0.1) )
begin
$display($realtime, "Warning : Cycle Violation");
pll_lock = 0;
locked_tmp = 0;
end
pll_rising_edge_count = pll_rising_edge_count + 1;
pll_last_rising_edge = $realtime;
end
always @(negedge clk)
begin
if (pll_rising_edge_count == 1)
begin
pll1_half_period = ($realtime - pll_last_rising_edge)/clk0_multiply_by;
pll2_half_period = ($realtime - pll_last_rising_edge)/clk1_multiply_by;
pll_duty_cycle = $realtime - pll_last_rising_edge;
end
else if ( ($realtime - pll_last_rising_edge) < (pll_duty_cycle - 0.1) ||
($realtime - pll_last_rising_edge) > (pll_duty_cycle + 0.1) )
begin
$display($realtime, "Warning: Duty Cycle Violation");
pll_lock = 0;
locked_tmp = 0;
end
pll_last_falling_edge = $realtime;
end
always @(pll_rising_edge_count)
begin
if (pll_rising_edge_count > 2)
begin
for (i=1; i<= 2*clk0_multiply_by - 1; i=i+1)
begin
clk0_count = clk0_count + 1;
#pll1_half_period;
end
clk0_count = clk0_count + 1;
end
else
clk0_count = 0;
end
always @(pll_rising_edge_count)
begin
if (pll_rising_edge_count > 2) // pll locks after 2 cycles
begin
for (j=1; j<= 2*clk1_multiply_by - 1; j=j+1)
begin
clk1_count = clk1_count + 1;
#pll2_half_period;
end
clk1_count = clk1_count + 1;
end
else
clk1_count = 0;
end
always @(clk0_count)
begin
if (clk0_count <= 0)
clkout0_tmp = 1'b0;
else if (pll_lock == 0)
clkout0_tmp = 1'b0;
else if (clk0_count == 1)
begin
locked_tmp = 1'b1;
clkout0_tmp = start_inclk;
new_inclk0 = ~start_inclk;
end
else
begin
clkout0_tmp = new_inclk0;
new_inclk0 = ~new_inclk0;
end
end
always @(clk1_count)
begin
if (clk1_count <= 0)
clkout1_tmp = 1'b0;
else if (pll_lock == 0)
clkout1_tmp = 1'b0;
else if (clk1_count == 1)
begin
locked_tmp = 1'b1;
clkout1_tmp = start_inclk;
new_inclk1 = ~start_inclk;
end
else
begin
clkout1_tmp = new_inclk1;
new_inclk1 = ~new_inclk1;
end
end
// ACCELERATE OUTPUTS
assign clk0 = clkout0_tmp;
assign clk1 = clkout1_tmp;
assign locked = locked_tmp;
endmodule