?? maxii_atoms.v
字號:
begin
$display("Error! widthdata parameter must be equal to 16.");
end
addr_reg <= 0;
for (n=0; n < widthdata; n=n+1)
data_reg[n] <= 1'bx;
program_pulse <= 0;
erase_pulse <= 0;
storage_output <= 0;
// Initialize UFM
numwords = 1 << address_width;
if (init_file == "none")
for (i=0; i<numwords; i=i+1)
ufm_storage[i] = 16'hFFFF; // UFM content is initially all 1's
else
begin
// initialize UFM from memory initialization file (*.mif or *.hex)
// the contents of the memory initialization file are passed in via the
// mem* parameters
ufm_initf_sec1 = {mem16, mem15, mem14, mem13, mem12, mem11, mem10, mem9};
ufm_initf_sec0 = {mem8, mem7, mem6, mem5, mem4, mem3, mem2, mem1};
for (mem_cnt = 1; mem_cnt <= sector0_range; mem_cnt = mem_cnt + 1)
begin
for (bit_cnt = 0; bit_cnt < widthdata; bit_cnt = bit_cnt + 1)
begin
init_word0[bit_cnt] = ufm_initf_sec0[((mem_cnt-1)*widthdata) + bit_cnt];
init_word1[bit_cnt] = ufm_initf_sec1[((mem_cnt-1)*widthdata) + bit_cnt];
end
//sector 0
ufm_storage[mem_cnt-1] = init_word0;
//sector 1
ufm_storage[(mem_cnt-1)+sector0_range] = init_word1;
end
end
end
// ALWAYS CONSTRUCT BLOCKS
// Produce oscillation clock to UFM
always @(int_osc or i_oscena)
begin
if (i_oscena === 'b1)
begin
if (first_warning == 1)
begin
$display("Info : UFM oscillator can operate at any frequency between 3.33MHz to 5.56Mhz.");
first_warning = 0;
end
if (int_osc === 'b0 || int_osc === 'b1)
osc_str <= #TOSCMN_PW ~int_osc;
else
osc_str <= #TOSCMN_PW 0;
end
else
begin
osc_str <= #TOSCMN_PW 1;
end
end
// Shift address from LSB to MSB when arshft is '1'; else increment address.
// (Using block statement to avoid race condition warning; therefore, the
// order of assignments must be taken care to ensure correct behaviour)
always @(posedge gated_arclk or negedge devclrn or negedge devpor)
begin
if (devpor == 'b0)
addr_reg = 0;
else if (devclrn == 'b0)
addr_reg = 0;
else if (i_arshft == 'b1)
begin
for (i=address_width-1; i >= 1; i=i-1)
begin
addr_reg[i] = addr_reg[i-1];
end
addr_reg[0] = i_ardin;
end
else
addr_reg = addr_reg + 1;
end
// Latest address
always @(address_tmp)
begin
address_now <= address_tmp;
end
// Shift data from LSB to MSB when drshft is '1'; else load new data.
// (Using block statement to avoid race condition warning; therefore, the
// order of assignments must be taken care to ensure correct behaviour)
always @(posedge gated_drclk or negedge devclrn or negedge devpor)
begin
if (devpor == 'b0)
data_reg = 0;
else if (devclrn == 'b0)
data_reg = 0;
else if (i_drshft == 'b1)
begin
for (j=widthdata-1; j >= 1; j=j-1)
begin
data_reg[j] = data_reg[j-1];
end
data_reg[0] = i_drdin;
end
else
data_reg = storage_output;
end
// Latest data loaded from ufm
always @(new_read_data)
begin
storage_output <= new_read_data;
end
// Latest data content in data register
always @(data_tmp)
begin
data_now <= data_tmp;
end
always @(posedge int_osc)
begin
program_reg <= i_program;
// PROGRAM has higher precedence than ERASE
if(i_program !== 'b1)
erase_reg <= i_erase;
end
// Pulse to indicate programing UFM for min of 20ms and max of 40ms
// (must use blocking statement)
always @(posedge program_reg)
begin
if (program_pulse !== 'b1)
begin
program_pulse = 1;
program_pulse = #(TPPMX) 0;
end
end
// Pulse to indicate erasing UFM for min of 20ms and max of 120ms
// (must use blocking statement)
always @(posedge erase_reg)
begin
if (erase_pulse !== 'b1)
begin
erase_pulse = 1;
// Create a pulse of TEPMX * 1000 ps
for (l=1; l < 1000; l=l+1)
begin
erase_pulse = #(TEPMX) 1;
end
erase_pulse = #(TEPMX) 0;
end
end
// Start updating UFM
always @(posedge program_pulse)
begin
// The write operation is the logical "AND" in UFM
ufm_storage[address_now] <= data_now & ufm_storage[address_now];
end
// Start erasing UFM
always @(posedge erase_pulse)
begin
if (address_now[address_width-1] == 'b0)
begin
for (k=0; k<sector0_range; k=k+1)
begin
ufm_storage[k] <= 16'hFFFF; // Data in UFM is erased to all 1's
end
end
else
begin
for (k=sector0_range; k<sector0_range*2; k=k+1)
begin
ufm_storage[k] <= 16'hFFFF; // Data in UFM is erased to all 1's
end
end
end
// CONTINUOUS ASSIGNMENT
and(busy, sys_busy, 'b1);
and(osc, int_osc, 'b1);
and(sbdout, i_sbdin, 'b1);
and(bgpbusy, ctrl_bgpbusy, 'b1);
and(drdout, data_reg_msb, 'b1);
assign data_reg_msb = data_tmp[(widthdata-1)];
assign address_tmp = addr_reg;
assign data_tmp = data_reg;
assign new_read_data = ufm_storage[address_tmp];
assign sys_busy = program_pulse | erase_pulse;
assign int_osc = osc_str;
assign gated_arclk = i_arclk & !sys_busy;
assign gated_drclk = i_drclk & !sys_busy;
endmodule // maxii_ufm
///////////////////////////////////////////////////////////////////////////////
//
// MAXII IO Atom
//
///////////////////////////////////////////////////////////////////////////////
`timescale 1 ps/1 ps
module maxii_io (
datain,
oe,
padio,
combout
);
input datain;
input oe;
output combout;
inout padio;
parameter operation_mode = "input";
parameter bus_hold = "false";
parameter open_drain_output = "false";
parameter lpm_type = "maxii_io";
reg prev_value;
reg tmp_padio;
reg tmp_combout;
reg buf_control;
reg iopen_drain; // open_drain: 1--true, 0--false
reg ibus_hold; // bus_hold: 1--true, 0--false
reg [1:0] iop_mode; // operation_mode: 1--input, 2--output, 3--bidir
wire datain_in;
wire oe_in;
buf(datain_in, datain);
buf(oe_in, oe);
tri padio_tmp;
specify
(padio => combout) = (0,0);
(datain => padio) = (0, 0);
(posedge oe => (padio +: padio_tmp)) = (0, 0);
(negedge oe => (padio +: 1'bz)) = (0, 0);
endspecify
initial
begin
prev_value = 'b0;
tmp_padio = 'bz;
if (operation_mode == "input")
iop_mode = 1;
else if (operation_mode == "output")
iop_mode = 2;
else if (operation_mode == "bidir")
iop_mode = 3;
else
begin
$display ("Error: Invalid operation_mode specified\n");
iop_mode = 0;
end
if (bus_hold == "true" )
ibus_hold = 1;
else
ibus_hold = 0;
if (open_drain_output == "true" )
iopen_drain = 1;
else
iopen_drain = 0;
end
always @(datain_in or oe_in or padio)
begin
if (ibus_hold == 1)
begin
buf_control = 'b1;
if ( operation_mode == "input")
begin
if (padio == 1'bz)
tmp_combout = prev_value;
else
begin
prev_value = padio;
tmp_combout = padio;
end
tmp_padio = 1'bz;
end
else
begin
if (iop_mode == 2 || iop_mode == 3)
begin
if (oe_in == 1)
begin
if (iopen_drain == 1)
begin
if (datain_in == 0)
begin
tmp_padio = 1'b0;
prev_value = 1'b0;
end
else if (datain_in == 1'bx)
begin
tmp_padio = 1'bx;
prev_value = 1'bx;
end
else // output of tri is 'Z'
begin
if (iop_mode == 3)
prev_value = padio;
tmp_padio = 1'bz;
end
end
else // open_drain_output = false;
begin
tmp_padio = datain_in;
prev_value = datain_in;
end
end
else if (oe_in == 0)
begin
if (iop_mode == 3)
prev_value = padio;
tmp_padio = 1'bz;
end
else // oe == 'X'
begin
tmp_padio = 1'bx;
prev_value = 1'bx;
end
end
if (iop_mode == 2)
tmp_combout = 1'bz;
else
tmp_combout = padio;
end
end
else // bus hold is false
begin
buf_control = 'b0;
if (iop_mode == 1)
begin
tmp_combout = padio;
end
else if (iop_mode == 2 || iop_mode == 3)
begin
if (iop_mode == 3)
tmp_combout = padio;
if (oe_in == 1)
begin
if (iopen_drain == 1)
begin
if (datain_in == 0)
tmp_padio = 1'b0;
else if (datain_in == 1'bx)
tmp_padio = 1'bx;
else
tmp_padio = 1'bz;
end
else
tmp_padio = datain_in;
end
else if (oe_in == 0)
tmp_padio = 1'bz;
else
tmp_padio = 1'bx;
end
else
$display ("Error: Invalid operation_mode specified in MAXII io atom!\n");
end
end
bufif1 (weak1, weak0) b(padio_tmp, prev_value, buf_control); //weak value
pmos (padio_tmp, tmp_padio, 'b0);
pmos (combout, tmp_combout, 'b0);
pmos (padio, padio_tmp, 'b0);
endmodule
//------------------------------------------------------------------
//
// Module Name : maxii_routing_wire
//
// Description : Simulation model for a simple routing wire
//
//------------------------------------------------------------------
`timescale 1ps / 1ps
module maxii_routing_wire (
datain,
dataout
);
// INPUT PORTS
input datain;
// OUTPUT PORTS
output dataout;
// INTERNAL VARIABLES
wire dataout_tmp;
specify
(datain => dataout) = (0, 0) ;
endspecify
assign dataout_tmp = datain;
and (dataout, dataout_tmp, 1'b1);
endmodule // maxii_routing_wire
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -