URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/boards/xilinx/ml501/bench/verilog
- from Rev 360 to Rev 412
- ↔ Reverse comparison
Rev 360 → Rev 412
/eth_stim.v
File deleted
\ No newline at end of file
/WireDelay.v
File deleted
/eth_phy_defines.v
File deleted
/eth_phy.v
File deleted
/ml501_testbench_defines.v
File deleted
\ No newline at end of file
/ml501_testbench.v
File deleted
/ddr2_model.v
1,10 → 1,10
/**************************************************************************************** |
* |
* File Name: ddr2.v |
* File Name: ddr2_model.v |
* Version: 5.80 |
* Model: BUS Functional |
* |
* Dependencies: ddr2_parameters.vh |
* Dependencies: ddr2_parameters.v |
* |
* Description: Micron SDRAM DDR2 (Double Data Rate 2) |
* |
137,7 → 137,7
odt |
); |
|
`include "ddr2_model_parameters.vh" |
`include "ddr2_model_parameters.v" |
|
// text macros |
`define DQ_PER_DQS DQ_BITS/DQS_BITS |
/include/eth_stim.v
0,0 → 1,1268
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Ethernet MAC Stimulus //// |
//// //// |
//// Description //// |
//// Ethernet MAC stimulus tasks. Taken from the project //// |
//// testbench in the ethmac core. //// |
//// //// |
//// To Do: //// |
//// //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// - Igor Mohor, igorM@opencores.org //// |
//// - Julius Baxter julius.baxter@orsoc.se //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
`define TIME $display("Time: %0t", $time) |
|
// Defines for ethernet test to trigger sending/receiving |
// Is straight forward when using RTL design, but if using netlist then paths to |
// the RX/TX enabled bits depend on synthesis tool, etc, but ones here appear to |
// work with design put through Synplify, with hierarchy maintained. |
`define ETH_TOP dut.ethmac0 |
`define ETH_BD_RAM_PATH `ETH_TOP.wishbone.bd_ram |
`define ETH_MODER_PATH `ETH_TOP.ethreg1.MODER_0 |
|
`ifdef RTL_SIM |
`ifdef ethmac_IS_GATELEVEL |
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.r_TxEn; |
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.r_RxEn; |
`else |
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.DataOut[1]; |
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.DataOut[0]; |
`endif |
`endif |
|
`ifdef GATE_SIM |
`define ETH_MODER_TXEN_BIT `ETH_MODER_PATH.r_TxEn; |
`define ETH_MODER_RXEN_BIT `ETH_MODER_PATH.r_RxEn; |
`endif |
|
reg [15:0] eth_stim_rx_packet_length; |
reg [7:0] st_data; |
reg [31:0] lfsr; |
integer lfsr_last_byte; |
|
// Is number of ethernet packets to send if doing the eth-rx test. |
parameter eth_stim_num_rx_only_num_packets = 500; // Set to 0 for continuous RX |
parameter eth_stim_num_rx_only_packet_size = 512; |
parameter eth_stim_num_rx_only_packet_size_change = 2'b01; // 2'b01: Increment |
parameter eth_stim_num_rx_only_packet_size_change_amount = 1; |
parameter eth_stim_num_rx_only_IPG = 800000; // ns |
|
// Do call/response test |
reg eth_stim_do_rx_reponse_to_tx; |
|
|
parameter num_tx_bds = 16; |
parameter num_tx_bds_mask = 4'hf; |
parameter num_rx_bds = 16; |
parameter num_rx_bds_mask = 4'hf; |
parameter max_eth_packet_size = 16'h0600; |
|
// If running eth-rxtxbig test (sending and receiving maximum packets), then |
// set this parameter to the max packet size, otherwise min packet size |
//parameter rx_while_tx_min_packet_size = max_eth_packet_size; |
parameter rx_while_tx_min_packet_size = 32; |
|
// Use the smallest possible IPG |
parameter eth_stim_use_min_IPG = 0; |
parameter eth_stim_IPG_delay_max = 500_000; // Maximum 500uS ga |
//parameter eth_stim_IPG_delay_max = 100_000_000; // Maximum 100mS between packets |
parameter eth_stim_IPG_min_10mb = 9600; // 9.6 uS |
parameter eth_stim_IPG_min_100mb = 800; // 860+~100 = 960 nS 100MBit min IPG |
parameter eth_stim_check_rx_packet_contents = 1; |
parameter eth_stim_check_tx_packet_contents = 1; |
|
parameter eth_inject_errors = 0; |
|
// When running simulations where you don't want to feed packets to the design |
// like this... |
parameter eth_stim_disable_rx_stim = 0; |
|
// Delay between seeing that the buffer descriptor for an RX packet says it's |
// been received and ending up in the memory. |
// For 25MHz sdram controller, use following: |
//parameter Td_rx_packet_check = (`BOARD_CLOCK_PERIOD * 2000); |
// For 64MHz sdram controller, use following: |
parameter Td_rx_packet_check = (`BOARD_CLOCK_PERIOD * 500); |
|
|
|
integer expected_rxbd;// init to 0 |
integer expected_txbd; |
|
wire ethmac_rxen; |
wire ethmac_txen; |
assign ethmac_rxen = eth_stim_disable_rx_stim ? 0 : `ETH_MODER_RXEN_BIT; |
assign ethmac_txen = `ETH_MODER_TXEN_BIT; |
|
integer eth_rx_num_packets_sent = 0; |
integer eth_rx_num_packets_checked = 0; |
integer num_tx_packets = 1; |
|
integer rx_packet_lengths [0:1023]; // Array of packet lengths |
|
|
integer speed_loop; |
|
// When txen is (re)enabled, the tx bd pointer goes back to 0 |
always @(posedge ethmac_txen) |
expected_txbd = 0; |
|
reg eth_stim_waiting; |
|
initial |
begin |
#1; |
//lfsr = 32'h84218421; // Init pseudo lfsr |
lfsr = 32'h00700001; // Init pseudo lfsr |
lfsr_last_byte = 0; |
|
eth_stim_waiting = 1; |
expected_rxbd = num_tx_bds; // init this here |
|
eth_stim_do_rx_reponse_to_tx = 0; |
|
|
while (eth_stim_waiting) // Loop, waiting for enabling of MAC by software |
begin |
#100; |
// If RX enable and not TX enable... |
if(ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1)) |
begin |
if (eth_inject_errors) |
begin |
do_rx_only_stim(16, 64, 0, 0); |
do_rx_only_stim(128, 64, 1'b1, 8); |
do_rx_only_stim(256, 64, 1'b1, 4); |
eth_stim_waiting = 0; |
end |
else |
begin |
//do_rx_only_stim(eth_stim_num_rx_only_num_packets, |
//eth_stim_num_rx_only_packet_size, 0, 0); |
|
// Call packet send loop directly. No error injection. |
send_packet_loop(eth_stim_num_rx_only_num_packets, |
eth_stim_num_rx_only_packet_size, |
eth_stim_num_rx_only_packet_size_change, |
eth_stim_num_rx_only_packet_size_change_amount, |
eth_phy0.eth_speed, // Speed |
eth_stim_num_rx_only_IPG, // IPG |
48'h0012_3456_789a, 48'h0708_090A_0B0C, 1, |
0, 0); |
|
eth_stim_waiting = 0; |
end |
end // if (ethmac_rxen === 1'b1 & !(ethmac_txen===1'b1)) |
// If both RX and TX enabled |
else if (ethmac_rxen === 1'b1 & ethmac_txen===1'b1) |
begin |
// Both enabled - let's wait for the first packet transmitted |
// to see what stimulus we should provide |
while (num_tx_packets==1) |
#1000; |
|
$display("* ethmac RX/TX test request: %x", eth_phy0.tx_mem[0]); |
|
// Check the first received byte's value |
case (eth_phy0.tx_mem[0]) |
0: |
begin |
// kickoff call/response here |
eth_stim_do_rx_reponse_to_tx = 1; |
end |
default: |
begin |
do_rx_while_tx_stim(1400); |
end |
endcase // case (eth_phy0.tx_mem[0]) |
|
eth_stim_waiting = 0; |
end |
end // while (eth_stim_waiting) |
|
end // initial begin |
|
// Main Ethernet RX testing stimulus task. |
// Sends a set of packets at both speeds |
task do_rx_only_stim; |
input [31:0] num_packets; |
input [31:0] start_packet_size; |
input inject_errors; |
input [31:0] inject_errors_mod; |
|
begin |
|
for(speed_loop=1;speed_loop<3;speed_loop=speed_loop+1) |
begin |
|
send_packet_loop(num_packets, start_packet_size, 2'b01, 1, |
speed_loop[0], 10000, |
48'h0012_3456_789a, 48'h0708_090A_0B0C, 1, |
inject_errors, inject_errors_mod); |
|
end |
|
end |
endtask // do_rx_stim |
|
// Generate RX packets while there's TX going on |
// Sends a set of packets at both speeds |
task do_rx_while_tx_stim; |
input [31:0] num_packets; |
reg [31:0] IPG; // Inter-packet gap |
reg [31:0] packet_size; |
|
integer j; |
begin |
|
for(j=0;j<num_packets;j=j+1) |
begin |
// Determine delay between RX packets: |
|
if (eth_stim_use_min_IPG) |
begin |
// Assign based on whether we're in 100mbit or 10mbit mode |
IPG = eth_phy0.eth_speed ? eth_stim_IPG_min_100mb : |
eth_stim_IPG_min_10mb; |
// Add a little bit of variability |
// Add up to 15 |
IPG = IPG + ($random & 32'h000000f); |
end |
else |
begin |
IPG = $random; |
|
while (IPG > eth_stim_IPG_delay_max) |
IPG = IPG / 2; |
|
|
end |
$display("do_rx_while_tx IPG = %0d", IPG); |
// Determine size of next packet: |
if (rx_while_tx_min_packet_size == max_eth_packet_size) |
// We want to transmit biggest packets possible, easy case |
packet_size = max_eth_packet_size - 4; |
else |
begin |
// Constrained random sized packets |
packet_size = $random; |
|
while (packet_size > (max_eth_packet_size-4)) |
packet_size = packet_size / 2; |
|
// Now divide by least significant bits of j |
packet_size = packet_size / {29'd0,j[1:0],1'b1}; |
if (packet_size < 60) |
packet_size = packet_size + 60; |
end |
|
$display("do_rx_while_tx packet_size = %0d", packet_size); |
send_packet_loop(1, packet_size, 2'b01, 1, eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0); |
|
// If RX enable went low, wait for it go high again |
if (ethmac_rxen===1'b0) |
begin |
|
while (ethmac_rxen===1'b0) |
begin |
@(posedge ethmac_rxen); |
#10000; |
end |
|
// RX disabled and when re-enabled we reset the buffer descriptor number |
expected_rxbd = num_tx_bds; |
|
end |
|
end // for (j=0;j<num_packets;j=j+1) |
end |
endtask // do_rx_stim |
|
// Registers used in detecting transmitted packets |
reg eth_stim_tx_loop_keep_polling; |
reg [31:0] ethmac_txbd_lenstat, ethmac_last_txbd_lenstat; |
reg eth_stim_detected_packet_tx; |
|
// If in call-response mode, whenever we receive a TX packet, we generate |
// one and send it back |
always @(negedge eth_stim_detected_packet_tx) |
begin |
if (eth_stim_do_rx_reponse_to_tx & ethmac_rxen) |
// Continue if we are enabled |
do_rx_response_to_tx(); |
end |
|
// Generate RX packet in rsponse to TX packet |
task do_rx_response_to_tx; |
//input unused; |
|
reg [31:0] IPG; // Inter-packet gap |
reg [31:0] packet_size; |
|
integer j; |
begin |
|
// Get packet size test wants us to send |
packet_size = {eth_phy0.tx_mem[0],eth_phy0.tx_mem[1], |
eth_phy0.tx_mem[2],eth_phy0.tx_mem[3]}; |
|
|
IPG = {eth_phy0.tx_mem[4],eth_phy0.tx_mem[5], |
eth_phy0.tx_mem[6],eth_phy0.tx_mem[7]}; |
|
|
$display("do_rx_response_to_tx IPG = %0d", IPG); |
if (packet_size == 0) |
begin |
// Constrained random sized packets |
packet_size = $random; |
|
while (packet_size > (max_eth_packet_size-4)) |
packet_size = packet_size / 2; |
|
if (packet_size < 60) |
packet_size = packet_size + 60; |
end |
|
$display("do_rx_response_to_tx packet_size = %0d", packet_size); |
send_packet_loop(1, packet_size, 2'b01, 1, eth_phy0.eth_speed, |
IPG, 48'h0012_3456_789a, |
48'h0708_090A_0B0C, 1, 1'b0, 0); |
|
// If RX enable went low, wait for it go high again |
if (ethmac_rxen===1'b0) |
begin |
|
while (ethmac_rxen===1'b0) |
begin |
@(posedge ethmac_rxen); |
#10000; |
end |
|
// RX disabled and when re-enabled we reset the buffer |
// descriptor number |
expected_rxbd = num_tx_bds; |
|
end |
|
end |
endtask // do_rx_response_to_tx |
|
|
|
|
|
// |
// always@() to check the TX buffer descriptors |
// |
always @(posedge ethmac_txen) |
begin |
ethmac_last_txbd_lenstat = 0; |
eth_stim_tx_loop_keep_polling=1; |
// Wait on the TxBD Ready bit |
while(eth_stim_tx_loop_keep_polling) |
begin |
#10; |
get_bd_lenstat(expected_txbd, ethmac_txbd_lenstat); |
// Check if we've finished transmitting this BD |
if (!ethmac_txbd_lenstat[15] & ethmac_last_txbd_lenstat[15]) |
// Falling edge of TX BD Ready |
eth_stim_detected_packet_tx = 1; |
|
ethmac_last_txbd_lenstat = ethmac_txbd_lenstat; |
|
// If TX en goes low then exit |
if (!ethmac_txen) |
eth_stim_tx_loop_keep_polling = 0; |
else if (eth_stim_detected_packet_tx) |
begin |
// Wait until the eth_phy has finished receiving it |
while (eth_phy0.mtxen_i === 1'b1) |
#10; |
|
$display("(%t) Check TX packet: bd %d: 0x%h",$time, |
expected_txbd, ethmac_txbd_lenstat); |
|
// Check the TXBD, see if the packet transmitted OK |
if (ethmac_txbd_lenstat[8] | ethmac_txbd_lenstat[3]) |
begin |
// Error occured |
`TIME; |
$display("*E TX Error of packet %0d detected.", |
num_tx_packets); |
$display(" TX BD %0d = 0x%h", expected_txbd, |
ethmac_txbd_lenstat); |
if (ethmac_txbd_lenstat[8]) |
$display(" Underrun in MAC during TX"); |
if (ethmac_txbd_lenstat[3]) |
$display(" Retransmission limit hit"); |
|
$finish; |
end |
else |
begin |
// Packet was OK, let's compare the contents we |
// received with those that were meant to be transmitted |
if (eth_stim_check_tx_packet_contents) |
begin |
check_tx_packet(expected_txbd); |
expected_txbd = (expected_txbd + 1) & |
num_tx_bds_mask; |
num_tx_packets = num_tx_packets + 1; |
eth_stim_detected_packet_tx = 0; |
end |
end |
end |
end // while (eth_stim_tx_loop_keep_polling) |
end // always @ (posedge ethmac_txen) |
|
|
|
// |
// Check packet TX'd by MAC was good |
// |
task check_tx_packet; |
input [31:0] tx_bd_num; |
|
reg [31:0] tx_bd_addr; |
reg [7:0] phy_byte; |
|
reg [31:0] txpnt_wb; // Pointer in array to where data should be |
reg [24:0] txpnt_sdram; // Index in array of shorts for data in SDRAM |
// part |
reg [21:0] buffer; |
reg [7:0] sdram_byte; |
reg [31:0] tx_len_bd; |
|
integer i; |
integer failure; |
begin |
failure = 0; |
|
get_bd_lenstat(tx_bd_num, tx_len_bd); |
|
tx_len_bd = {15'd0,tx_len_bd[31:16]}; |
|
// Check, if length didn't have to be padded, that |
// amount transmitted was correct |
if ((tx_len_bd > 60)&(tx_len_bd != (eth_phy0.tx_len-4))) |
begin |
$display("*E TX packet sent length, %0d != length in TX BD, %0d", |
eth_phy0.tx_len-4, tx_len_bd); |
#100; |
$finish; |
end |
|
get_bd_addr(tx_bd_num, tx_bd_addr); |
|
// We're never going to be using more than about 256K of receive buffer |
// so let's lop off the top bit of the address pointer - we only want |
// the offset from the base of the memory bank |
txpnt_wb = {14'd0,tx_bd_addr[17:0]}; |
txpnt_sdram = tx_bd_addr[24:0]; |
|
// Variable we'll use for index in the PHY's TX buffer |
buffer = 0; // Start of TX data |
`ifdef VERSATILE_SDRAM |
for (i=0;i<tx_len_bd;i=i+1) |
begin |
//$display("Checking address in tx bd 0x%0h",txpnt_sdram); |
|
sdram0.get_byte(txpnt_sdram,sdram_byte); |
|
phy_byte = eth_phy0.tx_mem[buffer]; |
// Debugging output |
//$display("txpnt_sdram = 0x%h, sdram_byte = 0x%h, buffer = 0x%h, phy_byte = 0x%h", txpnt_sdram, sdram_byte, buffer, phy_byte); |
if (phy_byte !== sdram_byte) |
begin |
`TIME; |
$display("*E Wrong byte (%d) of TX packet! ram = %h, phy = %h",buffer, sdram_byte, phy_byte); |
failure = 1; |
end |
|
buffer = buffer + 1; |
|
txpnt_sdram = txpnt_sdram+1; |
|
end // for (i=0;i<tx_len_bd;i=i+1) |
|
`else |
$display("SET ME UP TO LOOK IN ANOTHER MEMORY!"); |
$display("RAM pointer for BD is 0x%h, bank offset we'll use is 0x%h", |
tx_bd_addr, txpnt_wb); |
$finish; |
`endif // !`ifdef VERSATILE_SDRAM |
if (failure) |
begin |
#100 |
`TIME; |
$display("*E Error transmitting packet %0d (%0d bytes). Finishing simulation", num_tx_packets, tx_len_bd); |
get_bd_lenstat(tx_bd_num, tx_len_bd); |
$display(" TXBD lenstat: 0x%0h",tx_len_bd); |
$display(" TXBD address: 0x%0h",tx_bd_addr); |
$finish; |
end |
else |
begin |
#1 $display( "(%0t)(%m) TX packet %0d: %0d bytes in memory OK!",$time,num_tx_packets, tx_len_bd); |
|
end |
|
|
end |
endtask // check_tx_packet |
|
// |
// Task to send a set of packets |
// |
task send_packet_loop; |
input [31:0] num_packets; |
input [31:0] length; |
input [1:0] length_change; // 0 = none, 1 = incr, 2 = decrement |
input [31:0] length_change_size; // Size to change by |
input speed; |
input [31:0] back_to_back_delay; // #delay setting between packets |
input [47:0] dst_mac; |
input [47:0] src_mac; |
input random_fill; |
input random_errors; |
input [31:0] random_error_mod; |
integer j; |
reg error_this_time; |
integer error_type; // 0 = rxerr, 1=bad preamble 2=bad crc 3=TODO |
reg [31:0] rx_bd_lenstat; |
begin |
error_type = 0; |
error_this_time = 0; |
|
if (num_packets == 0) |
// Loop forever when num_packets is 0 |
num_packets = 32'h7fffffff; |
|
|
if (speed & !(eth_phy0.control_bit14_10[13] === 1'b1)) |
begin |
// write to phy's control register for 100Mbps |
eth_phy0.control_bit14_10 = 5'b01000; // bit 13 set - speed 100 |
// Swapping speeds, give some delay |
#10000; |
end |
else if (!speed & !(eth_phy0.control_bit14_10[13] === 1'b0)) |
begin |
eth_phy0.control_bit14_10 = 5'b00000; // bit 13 reset - speed 10 |
// Swapping speeds, give some delay |
#10000; |
end |
|
eth_phy0.control_bit8_0 = 9'h1_00; |
|
for(j=0;j<num_packets | length <32;j=j+1) |
begin |
eth_stim_rx_packet_length = length[15:0]; // Bytes |
st_data = 8'h0F; |
|
// setup RX packet in buffer - length is without CRC |
set_rx_packet(0, eth_stim_rx_packet_length, 1'b0, dst_mac, |
src_mac, 16'h0D0E, st_data, random_fill); |
|
set_rx_addr_type(0, dst_mac, src_mac, 16'h0D0E); |
|
// Error type 2 is cause CRC error |
append_rx_crc(0, eth_stim_rx_packet_length, 1'b0, |
(error_type==2)); |
|
if (error_this_time) |
begin |
if (error_type == 0) |
// RX ERR assert during transmit |
eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, |
8'hD5, 0, |
eth_stim_rx_packet_length+4, |
1'b0, 1'b1); |
else if (error_type == 1) |
// Incorrect preamble |
eth_phy0.send_rx_packet(64'h0055_5f55_5555_5555, 4'h7, |
8'hD5, 0, |
eth_stim_rx_packet_length+4, |
1'b0, 1'b0); |
else |
// Normal datapacket |
eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, |
8'hD5, 0, |
eth_stim_rx_packet_length+4, |
1'b0, 1'b0); |
end |
else |
eth_phy0.send_rx_packet(64'h0055_5555_5555_5555, 4'h7, 8'hD5, |
0, eth_stim_rx_packet_length+4, 1'b0, |
1'b0); |
|
|
// if RX enable still set (might have gone low during this packet |
if (ethmac_rxen) |
begin |
if (error_this_time) |
// Put in dummy length, checking function will skip... |
rx_packet_lengths[(eth_rx_num_packets_sent& 12'h3ff)]=32'heeeeeeee; |
else |
rx_packet_lengths[(eth_rx_num_packets_sent & 12'h3ff)] = length; |
|
eth_rx_num_packets_sent = eth_rx_num_packets_sent + 1; |
|
end // if (ethmac_rxen) |
else |
begin |
// Force the loop to finish up |
j = num_packets; |
end |
|
|
// Inter-packet gap |
#back_to_back_delay; |
|
// Update length |
if (length_change == 2'b01) |
length = length + length_change_size; |
|
if ((length_change == 2'b10) && |
((length - length_change_size) > 32)) |
length = length - length_change_size; |
|
// Increment error type |
if (error_this_time) |
error_type = error_type + 1; |
if (error_type > 3) |
error_type = 0; |
|
|
// Check if we should put in an error this time |
if (j%random_error_mod == 0) |
error_this_time = 1; |
else |
error_this_time = 0; |
|
eth_phy0.rx_err(0); |
|
// Now wait to check if we have filled up all the RX BDs and |
// the this packet would start writing over them. Only really an |
// issue when doing minimum IPG tests. |
while(((eth_rx_num_packets_sent+1) - eth_rx_num_packets_checked) |
== num_rx_bds) |
#100; |
|
|
end // for (j=0;j<num_packets | length <32;j=j+1) |
end |
endtask // send_packet_loop |
|
// Local buffer of "sent" data to the ethernet MAC, we will check against |
// Size of our local buffer in bytes |
parameter eth_rx_sent_circbuf_size = (16*1024); |
parameter eth_rx_sent_circbuf_size_mask = eth_rx_sent_circbuf_size - 1; |
integer eth_rx_sent_circbuf_fill_ptr = 0; |
integer eth_rx_sent_circbuf_read_ptr = 0; |
// The actual buffer |
reg [7:0] eth_rx_sent_circbuf [0:eth_rx_sent_circbuf_size-1]; |
|
/* |
TASKS for set and check RX packets: |
----------------------------------- |
set_rx_packet |
(rxpnt[31:0], len[15:0], plus_nibble, d_addr[47:0], s_addr[47:0], type_len[15:0], start_data[7:0]); |
check_rx_packet |
(rxpnt_phy[31:0], rxpnt_wb[31:0], len[15:0], plus_nibble, successful_nibble, failure[31:0]); |
*/ |
task set_rx_packet; |
input [31:0] rxpnt; // pointer to place in in the phy rx buffer we'll start at |
input [15:0] len; |
input plus_dribble_nibble; // if length is longer for one nibble |
input [47:0] eth_dest_addr; |
input [47:0] eth_source_addr; |
input [15:0] eth_type_len; |
input [7:0] eth_start_data; |
input random_fill; |
integer i, sd; |
reg [47:0] dest_addr; |
reg [47:0] source_addr; |
reg [15:0] type_len; |
reg [21:0] buffer; |
reg delta_t; |
|
begin |
buffer = rxpnt[21:0]; |
dest_addr = eth_dest_addr; |
source_addr = eth_source_addr; |
type_len = eth_type_len; |
sd = eth_start_data; |
delta_t = 0; |
for(i = 0; i < len; i = i + 1) |
begin |
if (i < 6) |
begin |
eth_phy0.rx_mem[buffer] = dest_addr[47:40]; |
dest_addr = dest_addr << 8; |
end |
else if (i < 12) |
begin |
eth_phy0.rx_mem[buffer] = source_addr[47:40]; |
source_addr = source_addr << 8; |
end |
else if (i < 14) |
begin |
eth_phy0.rx_mem[buffer] = type_len[15:8]; |
type_len = type_len << 8; |
end |
else |
begin |
if (random_fill) |
begin |
if (lfsr_last_byte == 0) |
eth_phy0.rx_mem[buffer] = lfsr[15:8]; |
if (lfsr_last_byte == 1) |
eth_phy0.rx_mem[buffer] = lfsr[23:16]; |
if (lfsr_last_byte == 2) |
eth_phy0.rx_mem[buffer] = lfsr[31:24]; |
if (lfsr_last_byte == 3) |
begin |
eth_phy0.rx_mem[buffer] = lfsr[7:0]; |
lfsr = {lfsr[30:0],(((lfsr[31] ^ lfsr[6]) ^ |
lfsr[5]) ^ lfsr[1])}; |
lfsr_last_byte = 0; |
end |
else |
lfsr_last_byte = lfsr_last_byte + 1; |
|
end // if (random_fill) |
else |
eth_phy0.rx_mem[buffer] = sd[7:0]; |
sd = sd + 1; |
end // else: !if(i < 14) |
|
// Update our local buffer |
eth_rx_sent_circbuf[eth_rx_sent_circbuf_fill_ptr] |
= eth_phy0.rx_mem[buffer]; |
eth_rx_sent_circbuf_fill_ptr = (eth_rx_sent_circbuf_fill_ptr+1)& |
eth_rx_sent_circbuf_size_mask; |
|
buffer = buffer + 1; |
end // for (i = 0; i < len; i = i + 1) |
|
delta_t = !delta_t; |
if (plus_dribble_nibble) |
eth_phy0.rx_mem[buffer] = {4'h0, 4'hD /*sd[3:0]*/}; |
delta_t = !delta_t; |
end |
endtask // set_rx_packet |
|
|
|
|
task set_rx_addr_type; |
input [31:0] rxpnt; |
input [47:0] eth_dest_addr; |
input [47:0] eth_source_addr; |
input [15:0] eth_type_len; |
integer i; |
reg [47:0] dest_addr; |
reg [47:0] source_addr; |
reg [15:0] type_len; |
reg [21:0] buffer; |
reg delta_t; |
begin |
buffer = rxpnt[21:0]; |
dest_addr = eth_dest_addr; |
source_addr = eth_source_addr; |
type_len = eth_type_len; |
delta_t = 0; |
for(i = 0; i < 14; i = i + 1) |
begin |
if (i < 6) |
begin |
eth_phy0.rx_mem[buffer] = dest_addr[47:40]; |
dest_addr = dest_addr << 8; |
end |
else if (i < 12) |
begin |
eth_phy0.rx_mem[buffer] = source_addr[47:40]; |
source_addr = source_addr << 8; |
end |
else // if (i < 14) |
begin |
eth_phy0.rx_mem[buffer] = type_len[15:8]; |
type_len = type_len << 8; |
end |
buffer = buffer + 1; |
end |
delta_t = !delta_t; |
end |
endtask // set_rx_addr_type |
|
|
// Check if we're using a synthesized version of eth module |
`ifdef ethmac_IS_GATELEVEL |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_lenstat; |
input [31:0] bd_num;// Number of ethernet BD to check |
output [31:0] bd_lenstat; |
`ifdef ACTEL |
reg [8:0] tmp; |
integer raddr; |
`endif |
begin |
`ifdef ACTEL |
|
// Pull from the Actel memory model |
raddr = `ETH_BD_RAM_PATH.\mem_tile.I_1 .get_address((bd_num*2)); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)]; |
bd_lenstat[8:0] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_lenstat[17:9] = tmp[8:0]; |
|
raddr = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .get_address((bd_num*2)); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)]; |
bd_lenstat[26:18] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_lenstat[31:27] = tmp[4:0]; |
|
//$display("(%t) read eth bd lenstat %h",$time, bd_lenstat); |
`endif |
end |
endtask // get_bd_lenstat |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_addr; |
input [31:0] bd_num;// Number of the ethernet BD to check |
output [31:0] bd_addr; |
`ifdef ACTEL |
reg [8:0] tmp; |
integer raddr; |
`endif |
begin |
`ifdef ACTEL |
// Pull from the Actel memory model |
raddr = `ETH_BD_RAM_PATH.\mem_tile.I_1 .get_address((bd_num*2)+1); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)]; |
bd_addr[8:0] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_addr[17:9] = tmp[8:0]; |
|
raddr = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .get_address((bd_num*2)+1); |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)]; |
bd_addr[26:18] = tmp[8:0]; |
|
tmp = `ETH_BD_RAM_PATH.\mem_tile_0.I_1 .MEM_512_9[(raddr*2)+1]; |
bd_addr[31:27] = tmp[4:0]; |
|
//$display("(%t) read eth bd%d addr %h",$time,bd_num, bd_addr); |
`endif |
end |
endtask // get_bd_addr |
|
`else // !`ifdef ethmac_IS_GATELEVEL |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_lenstat; |
input [31:0] bd_num;// Number of ethernet BD to check |
output [31:0] bd_lenstat; |
begin |
bd_lenstat = `ETH_BD_RAM_PATH.mem[(bd_num*2)]; |
end |
endtask // get_bd_lenstat |
|
// Get the length/status register of the ethernet buffer descriptor |
task get_bd_addr; |
input [31:0] bd_num;// Number of the ethernet BD to check |
output [31:0] bd_addr; |
begin |
bd_addr = `ETH_BD_RAM_PATH.mem[((bd_num*2)+1)]; |
//$display("(%t) read eth bd%d addr %h",$time,bd_num, bd_addr); |
end |
endtask // get_bd_addr |
`endif |
|
// Always block triggered by finishing of transmission of new packet from |
// send_packet_loop |
integer eth_rx_packet_length_to_check; |
|
always @* |
begin |
// Loop here until: |
// 1 - packets sent is not equal to packets checked (ie. some to check) |
// 2 - we're explicitly disabled for some reason |
// 3 - Receive has been disabled in the MAC |
while((eth_rx_num_packets_sent == eth_rx_num_packets_checked) || |
!eth_stim_check_rx_packet_contents || !(ethmac_rxen===1'b1)) |
#1000; |
|
eth_rx_packet_length_to_check |
= rx_packet_lengths[(eth_rx_num_packets_checked & 12'h3ff)]; |
|
if ( eth_rx_packet_length_to_check !== 32'heeeeeeee) |
check_rx_packet(expected_rxbd, 0, eth_rx_packet_length_to_check); |
|
eth_rx_num_packets_checked = eth_rx_num_packets_checked + 1; |
|
expected_rxbd = expected_rxbd + 1; |
|
// Wrap |
if (expected_rxbd == (num_tx_bds + num_rx_bds)) |
expected_rxbd = num_tx_bds; |
end |
|
task check_rx_packet; |
|
input [31:0] rx_bd_num; |
input [31:0] rxpnt_phy; // Pointer in array of data in PHY |
input [31:0] len; |
|
reg [31:0] rx_bd_lenstat; |
reg [31:0] rx_bd_addr; |
reg [7:0] phy_byte; |
|
reg [31:0] rxpnt_wb; // Pointer in array to where data should be |
reg [24:0] rxpnt_sdram; // byte address from CPU in RAM |
reg [15:0] sdram_short; |
reg [7:0] sdram_byte; |
//reg [7:0] phy_rx_mem [0:2000]; |
|
integer i; |
integer failure; |
|
begin |
|
failure = 0; |
|
// Wait until the buffer descriptor indicates the packet has been |
// received... |
get_bd_lenstat(rx_bd_num, rx_bd_lenstat); |
while (rx_bd_lenstat & 32'h00008000)// Check Empty bit |
begin |
#10; |
get_bd_lenstat(rx_bd_num, rx_bd_lenstat); |
//$display("(%t) check_rx_packet: poll bd %d: 0x%h",$time, |
// rx_bd_num, rx_bd_lenstat); |
end |
|
|
// Delay some time - takes a bit for the Wishbone FSM to pipe out the |
// packet over Wishbone and into whatever memory it's going into |
#Td_rx_packet_check; |
|
// Ok, buffer filled, let's get its offset in memory |
get_bd_addr(rx_bd_num, rx_bd_addr); |
|
$display("(%t) Check RX packet: bd %d: 0x%h, addr 0x%h",$time, |
rx_bd_num, rx_bd_lenstat, rx_bd_addr); |
|
|
// We're never going to be using more than about 256KB of receive buffer |
// so let's lop off the top bit of the address pointer - we only want |
// the offset from the base of the memory bank |
|
rxpnt_wb = {14'd0,rx_bd_addr[17:0]}; |
rxpnt_sdram = rx_bd_addr[24:0]; |
|
`ifdef VERSATILE_SDRAM |
// We'll look inside the SDRAM array |
// Hard coded for the SDRAM buffer area to be from the halfway mark in |
// memory (so starting in Bank2) |
// We'll be passed the offset from the beginning of the buffer area |
// in rxpnt_wb. This value will be in bytes. |
|
//$display("RAM pointer for BD is 0x%h, SDRAM addr is 0x%h", rx_bd_addr, rxpnt_sdram); |
|
|
for (i=0;i<len;i=i+1) |
begin |
|
sdram0.get_byte(rxpnt_sdram,sdram_byte); |
|
phy_byte = eth_rx_sent_circbuf[eth_rx_sent_circbuf_read_ptr];//phy_rx_mem[buffer]; //eth_phy0.rx_mem[buffer]; |
|
if (phy_byte !== sdram_byte) |
begin |
// `TIME; |
$display("*E Wrong byte (%5d) of RX packet %5d! phy = %h, ram = %h", |
i, eth_rx_num_packets_checked, phy_byte, sdram_byte); |
failure = 1; |
end |
|
eth_rx_sent_circbuf_read_ptr = (eth_rx_sent_circbuf_read_ptr+1)& |
eth_rx_sent_circbuf_size_mask; |
|
rxpnt_sdram = rxpnt_sdram+1; |
|
end // for (i=0;i<len;i=i+2) |
`else |
|
$display("SET ME UP TO LOOK IN ANOTHER MEMORY!"); |
$display("RAM pointer for BD is 0x%h, bank offset we'll use is 0x%h", |
rx_bd_addr, rxpnt_wb); |
$finish; |
|
|
`endif // !`ifdef VERSATILE_SDRAM |
|
if (failure) |
begin |
#100 |
`TIME; |
$display("*E Recieved packet %0d, length %0d bytes, had an error. Finishing simulation.", eth_rx_num_packets_checked, len); |
$finish; |
end |
else |
begin |
#1 $display( "(%0t)(%m) RX packet %0d: %0d bytes in memory OK!",$time,eth_rx_num_packets_checked, len); |
|
end |
end |
endtask // check_rx_packet |
|
|
////////////////////////////////////////////////////////////// |
// Ethernet CRC Basic tasks |
////////////////////////////////////////////////////////////// |
|
task append_rx_crc; |
input [31:0] rxpnt_phy; // source |
input [15:0] len; // length in bytes without CRC |
input plus_dribble_nibble; // if length is longer for one nibble |
input negated_crc; // if appended CRC is correct or not |
reg [31:0] crc; |
reg [7:0] tmp; |
reg [31:0] addr_phy; |
reg delta_t; |
begin |
addr_phy = rxpnt_phy + len; |
delta_t = 0; |
// calculate CRC from prepared packet |
paralel_crc_phy_rx(rxpnt_phy, {16'h0, len}, plus_dribble_nibble, crc); |
if (negated_crc) |
crc = ~crc; |
delta_t = !delta_t; |
|
if (plus_dribble_nibble) |
begin |
tmp = eth_phy0.rx_mem[addr_phy]; |
eth_phy0.rx_mem[addr_phy] = {crc[27:24], tmp[3:0]}; |
eth_phy0.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]}; |
eth_phy0.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]}; |
eth_phy0.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]}; |
eth_phy0.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]}; |
end |
else |
begin |
eth_phy0.rx_mem[addr_phy] = crc[31:24]; |
eth_phy0.rx_mem[addr_phy + 1] = crc[23:16]; |
eth_phy0.rx_mem[addr_phy + 2] = crc[15:8]; |
eth_phy0.rx_mem[addr_phy + 3] = crc[7:0]; |
end |
end |
endtask // append_rx_crc |
|
task append_rx_crc_delayed; |
input [31:0] rxpnt_phy; // source |
input [15:0] len; // length in bytes without CRC |
input plus_dribble_nibble; // if length is longer for one nibble |
input negated_crc; // if appended CRC is correct or not |
reg [31:0] crc; |
reg [7:0] tmp; |
reg [31:0] addr_phy; |
reg delta_t; |
begin |
addr_phy = rxpnt_phy + len; |
delta_t = 0; |
// calculate CRC from prepared packet |
paralel_crc_phy_rx(rxpnt_phy+4, {16'h0, len}-4, plus_dribble_nibble, crc); |
if (negated_crc) |
crc = ~crc; |
delta_t = !delta_t; |
|
if (plus_dribble_nibble) |
begin |
tmp = eth_phy0.rx_mem[addr_phy]; |
eth_phy0.rx_mem[addr_phy] = {crc[27:24], tmp[3:0]}; |
eth_phy0.rx_mem[addr_phy + 1] = {crc[19:16], crc[31:28]}; |
eth_phy0.rx_mem[addr_phy + 2] = {crc[11:8], crc[23:20]}; |
eth_phy0.rx_mem[addr_phy + 3] = {crc[3:0], crc[15:12]}; |
eth_phy0.rx_mem[addr_phy + 4] = {4'h0, crc[7:4]}; |
end |
else |
begin |
eth_phy0.rx_mem[addr_phy] = crc[31:24]; |
eth_phy0.rx_mem[addr_phy + 1] = crc[23:16]; |
eth_phy0.rx_mem[addr_phy + 2] = crc[15:8]; |
eth_phy0.rx_mem[addr_phy + 3] = crc[7:0]; |
end |
end |
endtask // append_rx_crc_delayed |
|
|
// paralel CRC calculating for PHY RX |
task paralel_crc_phy_rx; |
input [31:0] start_addr; // start address |
input [31:0] len; // length of frame in Bytes without CRC length |
input plus_dribble_nibble; // if length is longer for one nibble |
output [31:0] crc_out; |
reg [21:0] addr_cnt; // only 22 address lines |
integer word_cnt; |
integer nibble_cnt; |
reg [31:0] load_reg; |
reg delta_t; |
reg [31:0] crc_next; |
reg [31:0] crc; |
reg crc_error; |
reg [3:0] data_in; |
integer i; |
begin |
#1 addr_cnt = start_addr[21:0]; |
word_cnt = 24; // 27; // start of the frame - nibble granularity (MSbit first) |
crc = 32'hFFFF_FFFF; // INITIAL value |
delta_t = 0; |
// length must include 4 bytes of ZEROs, to generate CRC |
// get number of nibbles from Byte length (2^1 = 2) |
if (plus_dribble_nibble) |
nibble_cnt = ((len + 4) << 1) + 1'b1; // one nibble longer |
else |
nibble_cnt = ((len + 4) << 1); |
// because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3] |
load_reg[31:24] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[23:16] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[15: 8] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[ 7: 0] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
while (nibble_cnt > 0) |
begin |
// wait for delta time |
delta_t = !delta_t; |
// shift data in |
|
if(nibble_cnt <= 8) // for additional 8 nibbles shift ZEROs in! |
data_in[3:0] = 4'h0; |
else |
|
data_in[3:0] = {load_reg[word_cnt], load_reg[word_cnt+1], load_reg[word_cnt+2], load_reg[word_cnt+3]}; |
crc_next[0] = (data_in[0] ^ crc[28]); |
crc_next[1] = (data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29]); |
crc_next[2] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[30]); |
crc_next[3] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30] ^ crc[31]); |
crc_next[4] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28] ^ crc[30] ^ crc[31]) ^ crc[0]; |
crc_next[5] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[31]) ^ crc[1]; |
crc_next[6] = (data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30]) ^ crc[ 2]; |
crc_next[7] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28] ^ crc[30] ^ crc[31]) ^ crc[3]; |
crc_next[8] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[31]) ^ crc[4]; |
crc_next[9] = (data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30]) ^ crc[5]; |
crc_next[10] = (data_in[3] ^ data_in[2] ^ data_in[0] ^ crc[28] ^ crc[30] ^ crc[31]) ^ crc[6]; |
crc_next[11] = (data_in[3] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[31]) ^ crc[7]; |
crc_next[12] = (data_in[2] ^ data_in[1] ^ data_in[0] ^ crc[28] ^ crc[29] ^ crc[30]) ^ crc[8]; |
crc_next[13] = (data_in[3] ^ data_in[2] ^ data_in[1] ^ crc[29] ^ crc[30] ^ crc[31]) ^ crc[9]; |
crc_next[14] = (data_in[3] ^ data_in[2] ^ crc[30] ^ crc[31]) ^ crc[10]; |
crc_next[15] = (data_in[3] ^ crc[31]) ^ crc[11]; |
crc_next[16] = (data_in[0] ^ crc[28]) ^ crc[12]; |
crc_next[17] = (data_in[1] ^ crc[29]) ^ crc[13]; |
crc_next[18] = (data_in[2] ^ crc[30]) ^ crc[14]; |
crc_next[19] = (data_in[3] ^ crc[31]) ^ crc[15]; |
crc_next[20] = crc[16]; |
crc_next[21] = crc[17]; |
crc_next[22] = (data_in[0] ^ crc[28]) ^ crc[18]; |
crc_next[23] = (data_in[1] ^ data_in[0] ^ crc[29] ^ crc[28]) ^ crc[19]; |
crc_next[24] = (data_in[2] ^ data_in[1] ^ crc[30] ^ crc[29]) ^ crc[20]; |
crc_next[25] = (data_in[3] ^ data_in[2] ^ crc[31] ^ crc[30]) ^ crc[21]; |
crc_next[26] = (data_in[3] ^ data_in[0] ^ crc[31] ^ crc[28]) ^ crc[22]; |
crc_next[27] = (data_in[1] ^ crc[29]) ^ crc[23]; |
crc_next[28] = (data_in[2] ^ crc[30]) ^ crc[24]; |
crc_next[29] = (data_in[3] ^ crc[31]) ^ crc[25]; |
crc_next[30] = crc[26]; |
crc_next[31] = crc[27]; |
|
crc = crc_next; |
crc_error = crc[31:0] != 32'hc704dd7b; // CRC not equal to magic number |
case (nibble_cnt) |
9: crc_out = {!crc[24], !crc[25], !crc[26], !crc[27], !crc[28], !crc[29], !crc[30], !crc[31], |
!crc[16], !crc[17], !crc[18], !crc[19], !crc[20], !crc[21], !crc[22], !crc[23], |
!crc[ 8], !crc[ 9], !crc[10], !crc[11], !crc[12], !crc[13], !crc[14], !crc[15], |
!crc[ 0], !crc[ 1], !crc[ 2], !crc[ 3], !crc[ 4], !crc[ 5], !crc[ 6], !crc[ 7]}; |
default: crc_out = crc_out; |
endcase |
// wait for delta time |
delta_t = !delta_t; |
// increment address and load new data |
if ((word_cnt+3) == 7)//4) |
begin |
// because of MAGIC NUMBER nibbles are swapped [3:0] -> [0:3] |
load_reg[31:24] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[23:16] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[15: 8] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
load_reg[ 7: 0] = eth_phy0.rx_mem[addr_cnt]; |
addr_cnt = addr_cnt + 1; |
end |
// set new load bit position |
if((word_cnt+3) == 31) |
word_cnt = 16; |
else if ((word_cnt+3) == 23) |
word_cnt = 8; |
else if ((word_cnt+3) == 15) |
word_cnt = 0; |
else if ((word_cnt+3) == 7) |
word_cnt = 24; |
else |
word_cnt = word_cnt + 4;// - 4; |
// decrement nibble counter |
nibble_cnt = nibble_cnt - 1; |
// wait for delta time |
delta_t = !delta_t; |
end // while |
#1; |
end |
endtask // paralel_crc_phy_rx |
|
|
|
|
/include/eth_phy_defines.v
0,0 → 1,91
////////////////////////////////////////////////////////////////////// |
//// //// |
//// File name: eth_phy_defines.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// //// |
//// Author(s): //// |
//// - Tadej Markovic, tadej@opencores.org //// |
//// //// |
//// All additional information is available in the README.txt //// |
//// file. //// |
//// //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2002, Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2002/09/13 11:57:20 mohor |
// New testbench. Thanks to Tadej M - "The Spammer". |
// |
// |
// |
|
// Address of PHY device (LXT971A) |
`define ETH_PHY_ADDR 5'h00 //Changed to 0 -jb |
|
// LED/Configuration pins on PHY device - see the specification, page 26, table 8 |
// Initial set of bits 13, 12 and 8 of Control Register |
`define LED_CFG1 1'b0 |
`define LED_CFG2 1'b1 |
`define LED_CFG3 1'b1 |
|
|
// Supported speeds and physical ports - see the specification, page 67, table 41 |
// Set bits 15 to 9 of Status Register |
`define SUPPORTED_SPEED_AND_PORT 7'h3F |
|
// Extended status register (address 15) |
// Set bit 8 of Status Register |
`define EXTENDED_STATUS 1'b0 |
|
// Default status bits - see the specification, page 67, table 41 |
// Set bits 6 to 0 of Status Register |
`define DEFAULT_STATUS 7'h09 |
|
// PHY ID 1 number - see the specification, page 68, table 42 |
// Set bits of Phy Id Register 1 |
`define PHY_ID1 16'h0013 |
|
// PHY ID 2 number - see the specification, page 68, table 43 |
// Set bits 15 to 10 of Phy Id Register 2 |
`define PHY_ID2 6'h1E |
|
// Manufacturer MODEL number - see the specification, page 68, table 43 |
// Set bits 9 to 4 of Phy Id Register 2 |
`define MAN_MODEL_NUM 6'h0E |
|
// Manufacturer REVISION number - see the specification, page 68, table 43 |
// Set bits 3 to 0 of Phy Id Register 2 |
`define MAN_REVISION_NUM 4'h2 |
|
|
|
|
/include/ddr2_model_parameters.v
0,0 → 1,391
/**************************************************************************************** |
* |
* Disclaimer This software code and all associated documentation, comments or other |
* of Warranty: information (collectively "Software") is provided "AS IS" without |
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY |
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES |
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT |
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE |
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. |
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR |
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, |
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE |
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, |
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, |
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, |
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, |
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE |
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
* DAMAGES. Because some jurisdictions prohibit the exclusion or |
* limitation of liability for consequential or incidental damages, the |
* above limitation may not apply to you. |
* |
* Copyright 2003 Micron Technology, Inc. All rights reserved. |
* |
****************************************************************************************/ |
|
// Parameters current with 512Mb datasheet rev N |
|
// Timing parameters based on Speed Grade |
|
// SYMBOL UNITS DESCRIPTION |
`define sg37E |
`define x16 |
|
`ifdef sg37E |
parameter TCK_MIN = 3750; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 400; // tQHS ps Data hold skew factor |
parameter TAC = 500; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 225; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 450; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 300; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 250; // tIS ps Input Setup Time |
parameter TIH = 375; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 6; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`else // ------ ----- ----------- |
`ifdef sg187E |
parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 90; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 75; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 132; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 157; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 175; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 188; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 250; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 425; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 250; // tQHS ps Data hold skew factor |
parameter TAC = 350; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 0; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 75; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 175; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 125; // tIS ps Input Setup Time |
parameter TIH = 200; // tIH ps Input Hold Time |
parameter TRC = 54000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 13125; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 13125; // tRP ps Precharge command period |
parameter TRPA = 13125; // tRPA ps Precharge All period |
parameter TXARDS = 10; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 3; // tXARD tCK Exit active power down to a read command |
parameter TXP = 3; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 4; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 11; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 13125; // CL ps Minimum CAS Latency |
`else `ifdef sg25E |
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 100; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 150; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 175; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 200; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 200; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 300; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 300; // tQHS ps Data hold skew factor |
parameter TAC = 400; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 50; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 125; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 350; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 175; // tIS ps Input Setup Time |
parameter TIH = 250; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 12500; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 12500; // tRP ps Precharge command period |
parameter TRPA = 12500; // tRPA ps Precharge All period |
parameter TXARDS = 8; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 10; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 12500; // CL ps Minimum CAS Latency |
`else `ifdef sg25 |
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 100; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 150; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 175; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 200; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 200; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 300; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 300; // tQHS ps Data hold skew factor |
parameter TAC = 400; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 50; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 125; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 350; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 175; // tIS ps Input Setup Time |
parameter TIH = 250; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 8; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 10; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`else `ifdef sg3E |
parameter TCK_MIN = 3000; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 340; // tQHS ps Data hold skew factor |
parameter TAC = 450; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 175; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 240; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 200; // tIS ps Input Setup Time |
parameter TIH = 275; // tIH ps Input Hold Time |
parameter TRC = 54000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 12000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 12000; // tRP ps Precharge command period |
parameter TRPA = 12000; // tRPA ps Precharge All period |
parameter TXARDS = 7; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 12000; // CL ps Minimum CAS Latency |
`else `ifdef sg3 |
parameter TCK_MIN = 3000; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 125; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 340; // tQHS ps Data hold skew factor |
parameter TAC = 450; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 100; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 175; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 240; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 200; // tIS ps Input Setup Time |
parameter TIH = 275; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 7500; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 7; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`else `define sg5E |
parameter TCK_MIN = 5000; // tCK ps Minimum Clock Cycle Time |
parameter TJIT_PER = 125; // tJIT(per) ps Period JItter |
parameter TJIT_DUTY = 150; // tJIT(duty) ps Half Period Jitter |
parameter TJIT_CC = 250; // tJIT(cc) ps Cycle to Cycle jitter |
parameter TERR_2PER = 175; // tERR(nper) ps Accumulated Error (2-cycle) |
parameter TERR_3PER = 225; // tERR(nper) ps Accumulated Error (3-cycle) |
parameter TERR_4PER = 250; // tERR(nper) ps Accumulated Error (4-cycle) |
parameter TERR_5PER = 250; // tERR(nper) ps Accumulated Error (5-cycle) |
parameter TERR_N1PER = 350; // tERR(nper) ps Accumulated Error (6-10-cycle) |
parameter TERR_N2PER = 450; // tERR(nper) ps Accumulated Error (11-50-cycle) |
parameter TQHS = 450; // tQHS ps Data hold skew factor |
parameter TAC = 600; // tAC ps DQ output access time from CK/CK# |
parameter TDS = 150; // tDS ps DQ and DM input setup time relative to DQS |
parameter TDH = 275; // tDH ps DQ and DM input hold time relative to DQS |
parameter TDQSCK = 500; // tDQSCK ps DQS output access time from CK/CK# |
parameter TDQSQ = 350; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access |
parameter TIS = 350; // tIS ps Input Setup Time |
parameter TIH = 475; // tIH ps Input Hold Time |
parameter TRC = 55000; // tRC ps Active to Active/Auto Refresh command time |
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time |
parameter TWTR = 10000; // tWTR ps Write to Read command delay |
parameter TRP = 15000; // tRP ps Precharge command period |
parameter TRPA = 15000; // tRPA ps Precharge All period |
parameter TXARDS = 6; // tXARDS tCK Exit low power active power down to a read command |
parameter TXARD = 2; // tXARD tCK Exit active power down to a read command |
parameter TXP = 2; // tXP tCK Exit power down to a non-read command |
parameter TANPD = 3; // tANPD tCK ODT to power-down entry latency |
parameter TAXPD = 8; // tAXPD tCK ODT power-down exit latency |
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency |
`endif `endif `endif `endif `endif `endif |
|
`ifdef x16 |
`ifdef sg187E |
parameter TFAW = 45000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25E |
parameter TFAW = 45000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25 |
parameter TFAW = 45000; // tFAW ps Four Bank Activate window |
`else // sg3E, sg3, sg37E, sg5E |
parameter TFAW = 50000; // tFAW ps Four Bank Activate window |
`endif `endif `endif |
`else // x4, x8 |
`ifdef sg187E |
parameter TFAW = 35000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25E |
parameter TFAW = 35000; // tFAW ps Four Bank Activate window |
`else `ifdef sg25 |
parameter TFAW = 35000; // tFAW ps Four Bank Activate window |
`else // sg3E, sg3, sg37E, sg5E |
parameter TFAW = 37500; // tFAW ps Four Bank Activate window |
`endif `endif `endif |
`endif |
|
// Timing Parameters |
|
// Mode Register |
parameter AL_MIN = 0; // AL tCK Minimum Additive Latency |
parameter AL_MAX = 6; // AL tCK Maximum Additive Latency |
parameter CL_MIN = 3; // CL tCK Minimum CAS Latency |
parameter CL_MAX = 7; // CL tCK Maximum CAS Latency |
parameter WR_MIN = 2; // WR tCK Minimum Write Recovery |
parameter WR_MAX = 8; // WR tCK Maximum Write Recovery |
parameter BL_MIN = 4; // BL tCK Minimum Burst Length |
parameter BL_MAX = 8; // BL tCK Minimum Burst Length |
// Clock |
parameter TCK_MAX = 8000; // tCK ps Maximum Clock Cycle Time |
parameter TCH_MIN = 0.48; // tCH tCK Minimum Clock High-Level Pulse Width |
parameter TCH_MAX = 0.52; // tCH tCK Maximum Clock High-Level Pulse Width |
parameter TCL_MIN = 0.48; // tCL tCK Minimum Clock Low-Level Pulse Width |
parameter TCL_MAX = 0.52; // tCL tCK Maximum Clock Low-Level Pulse Width |
// Data |
parameter TLZ = TAC; // tLZ ps Data-out low-impedance window from CK/CK# |
parameter THZ = TAC; // tHZ ps Data-out high impedance window from CK/CK# |
parameter TDIPW = 0.35; // tDIPW tCK DQ and DM input Pulse Width |
// Data Strobe |
parameter TDQSH = 0.35; // tDQSH tCK DQS input High Pulse Width |
parameter TDQSL = 0.35; // tDQSL tCK DQS input Low Pulse Width |
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time) |
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time) |
parameter TWPRE = 0.35; // tWPRE tCK DQS Write Preamble |
parameter TWPST = 0.40; // tWPST tCK DQS Write Postamble |
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition |
// Command and Address |
parameter TIPW = 0.6; // tIPW tCK Control and Address input Pulse Width |
parameter TCCD = 2; // tCCD tCK Cas to Cas command delay |
parameter TRAS_MIN = 40000; // tRAS ps Minimum Active to Precharge command time |
parameter TRAS_MAX =70000000; // tRAS ps Maximum Active to Precharge command time |
parameter TRTP = 7500; // tRTP ps Read to Precharge command delay |
parameter TWR = 15000; // tWR ps Write recovery time |
parameter TMRD = 2; // tMRD tCK Load Mode Register command cycle time |
parameter TDLLK = 200; // tDLLK tCK DLL locking time |
// Refresh |
parameter TRFC_MIN = 105000; // tRFC ps Refresh to Refresh Command interval minimum value |
parameter TRFC_MAX =70000000; // tRFC ps Refresh to Refresh Command Interval maximum value |
// Self Refresh |
parameter TXSNR = TRFC_MIN + 10000; // tXSNR ps Exit self refesh to a non-read command |
parameter TXSRD = 200; // tXSRD tCK Exit self refresh to a read command |
parameter TISXR = TIS; // tISXR ps CKE setup time during self refresh exit. |
// ODT |
parameter TAOND = 2; // tAOND tCK ODT turn-on delay |
parameter TAOFD = 2.5; // tAOFD tCK ODT turn-off delay |
parameter TAONPD = 2000; // tAONPD ps ODT turn-on (precharge power-down mode) |
parameter TAOFPD = 2000; // tAOFPD ps ODT turn-off (precharge power-down mode) |
parameter TMOD = 12000; // tMOD ps ODT enable in EMR to ODT pin transition |
// Power Down |
parameter TCKE = 3; // tCKE tCK CKE minimum high or low pulse width |
|
// Size Parameters based on Part Width |
|
`ifdef x4 |
parameter ADDR_BITS = 14; // Address Bits |
parameter ROW_BITS = 14; // Number of Address bits |
parameter COL_BITS = 11; // Number of Column bits |
parameter DM_BITS = 1; // Number of Data Mask bits |
parameter DQ_BITS = 4; // Number of Data bits |
parameter DQS_BITS = 1; // Number of Dqs bits |
parameter TRRD = 7500; // tRRD Active bank a to Active bank b command time |
`else `ifdef x8 |
parameter ADDR_BITS = 14; // Address Bits |
parameter ROW_BITS = 14; // Number of Address bits |
parameter COL_BITS = 10; // Number of Column bits |
parameter DM_BITS = 1; // Number of Data Mask bits |
parameter DQ_BITS = 8; // Number of Data bits |
parameter DQS_BITS = 1; // Number of Dqs bits |
parameter TRRD = 7500; // tRRD Active bank a to Active bank b command time |
`else `define x16 |
parameter ADDR_BITS = 13; // Address Bits |
parameter ROW_BITS = 13; // Number of Address bits |
parameter COL_BITS = 10; // Number of Column bits |
parameter DM_BITS = 2; // Number of Data Mask bits |
parameter DQ_BITS = 16; // Number of Data bits |
parameter DQS_BITS = 2; // Number of Dqs bits |
parameter TRRD = 10000; // tRRD Active bank a to Active bank b command time |
`endif `endif |
|
`ifdef QUAD_RANK |
`define DUAL_RANK // also define DUAL_RANK |
parameter CS_BITS = 4; // Number of Chip Select Bits |
parameter RANKS = 4; // Number of Chip Select Bits |
`else `ifdef DUAL_RANK |
parameter CS_BITS = 2; // Number of Chip Select Bits |
parameter RANKS = 2; // Number of Chip Select Bits |
`else |
parameter CS_BITS = 2; // Number of Chip Select Bits |
parameter RANKS = 1; // Number of Chip Select Bits |
`endif `endif |
|
// Size Parameters |
parameter BA_BITS = 2; // Set this parmaeter to control how many Bank Address bits |
// if MEM_BITS== 14, a DQ=16 each part, DQ=64 total (4 parts) => 1MB total (256KB each) |
// if MEM_BITS== 15, a DQ=16 each part, DQ=64 total (4 parts) => 2MB total (512KB each) |
// if MEM_BITS== 16, a DQ=16 each part, DQ=64 total (4 parts) => 4MB total (1MB each) |
// if MEM_BITS== 17, a DQ=16 each part, DQ=64 total (4 parts) => 8MB total (2MB each) |
//parameter MEM_BITS = 14; // Number of write data bursts can be stored in memory. The default is 2^10=1024. |
parameter MEM_BITS = 17; // Number of write data bursts can be stored in memory. |
parameter AP = 10; // the address bit that controls auto-precharge and precharge-all |
parameter BL_BITS = 3; // the number of bits required to count to MAX_BL |
parameter BO_BITS = 2; // the number of Burst Order Bits |
|
// Simulation parameters |
parameter STOP_ON_ERROR = 1; // If set to 1, the model will halt on command sequence/major errors |
parameter DEBUG = 0; // Turn on Debug messages |
parameter BUS_DELAY = 0; // delay in nanoseconds |
parameter RANDOM_OUT_DELAY = 0; // If set to 1, the model will put a random amount of delay on DQ/DQS during reads |
parameter RANDOM_SEED = 711689044; //seed value for random generator. |
|
parameter RDQSEN_PRE = 2; // DQS driving time prior to first read strobe |
parameter RDQSEN_PST = 1; // DQS driving time after last read strobe |
parameter RDQS_PRE = 2; // DQS low time prior to first read strobe |
parameter RDQS_PST = 1; // DQS low time after last valid read strobe |
parameter RDQEN_PRE = 0; // DQ/DM driving time prior to first read data |
parameter RDQEN_PST = 0; // DQ/DM driving time after last read data |
parameter WDQS_PRE = 1; // DQS half clock periods prior to first write strobe |
parameter WDQS_PST = 1; // DQS half clock periods after last valid write strobe |
/include/ddr2_model_preload.v
0,0 → 1,56
// File intended to be included in the generate statement for each DDR2 part. |
// The following loads a vmem file, "sram.vmem" by default, into the SDRAM. |
|
// Wait until the DDR memory is initialised, and then magically |
// load it |
@(posedge dut.xilinx_ddr2_0.xilinx_ddr2_if0.phy_init_done); |
//$display("%t: Loading DDR2",$time); |
|
$readmemh("sram.vmem", program_array); |
/* Now dish it out to the DDR2 model's memory */ |
for(ram_ptr = 0 ; ram_ptr < 4096 ; ram_ptr = ram_ptr + 1) |
begin |
|
// Construct the burst line, with every second word from where we |
// started, and picking the correct half of the word with i%2 |
program_word_ptr = ram_ptr * 16 + (i/2) ; // Start on word0 or word1 |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[15:0] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
program_word_ptr = program_word_ptr + 2; |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[31:16] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
program_word_ptr = program_word_ptr + 2; |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[47:32] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
program_word_ptr = program_word_ptr + 2; |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[63:48] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
program_word_ptr = program_word_ptr + 2; |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[79:64] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
program_word_ptr = program_word_ptr + 2; |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[95:80] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
program_word_ptr = program_word_ptr + 2; |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[111:96] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
program_word_ptr = program_word_ptr + 2; |
tmp_program_word = program_array[program_word_ptr]; |
ddr2_ram_mem_line[127:112] = tmp_program_word[15 + ((i%2)*16):((i%2)*16)]; |
|
// Put this assembled line into the RAM using its memory writing TASK |
u_mem0.memory_write(2'b00,ram_ptr[19:7], |
{ram_ptr[6:0],3'b000},ddr2_ram_mem_line); |
|
//$display("Writing 0x%h, ramline=%d",ddr2_ram_mem_line, ram_ptr); |
|
end // for (ram_ptr = 0 ; ram_ptr < ... |
$display("(%t) * DDR2 RAM %1d preloaded",$time, i); |
end // initial begin |
/include/synthesis-defines.v
0,0 → 1,2
// Nothing in here, just providing synthesis-defines.v for files that include |
// it (clkgen, for one.) |
/include/timescale.v
0,0 → 1,2
`timescale 1ns/1ps |
/orpsoc_testbench.v
0,0 → 1,572
////////////////////////////////////////////////////////////////////// |
/// //// |
/// ORPSoC ML501 testbench //// |
/// //// |
/// Instantiate ORPSoC, monitors, provide stimulus //// |
/// //// |
/// Julius Baxter, julius@opencores.org //// |
/// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`include "orpsoc-defines.v" |
`include "orpsoc-testbench-defines.v" |
`include "test-defines.v" |
`include "timescale.v" |
// Xilinx simulation: |
`include "glbl.v" |
|
module orpsoc_testbench; |
|
// Clock and reset signal registers |
reg clk = 0; |
reg rst_n = 1; // Active LOW |
|
always |
#((`BOARD_CLOCK_PERIOD)/2) clk <= ~clk; |
|
wire clk_n, clk_p; |
assign clk_p = clk; |
assign clk_n = ~clk; |
|
|
// Reset, ACTIVE LOW |
initial |
begin |
#1; |
repeat (32) @(negedge clk) |
rst_n <= 1; |
repeat (32) @(negedge clk) |
rst_n <= 0; |
repeat (32) @(negedge clk) |
rst_n <= 1; |
end |
|
// Include design parameters file |
`include "orpsoc-params.v" |
|
// Pullup bus for I2C |
tri1 i2c_scl, i2c_sda; |
|
`ifdef JTAG_DEBUG |
wire tdo_pad_o; |
wire tck_pad_i; |
wire tms_pad_i; |
wire tdi_pad_i; |
`endif |
`ifdef UART0 |
wire uart0_stx_pad_o; |
wire uart0_srx_pad_i; |
`endif |
`ifdef GPIO0 |
wire [gpio0_io_width-1:0] gpio0_io; |
`endif |
`ifdef SPI0 |
wire spi0_mosi_o; |
wire spi0_miso_i; |
wire spi0_sck_o; |
wire spi0_hold_n_o; |
wire spi0_w_n_o; |
wire [spi0_ss_width-1:0] spi0_ss_o; |
`endif |
`ifdef ETH0 |
wire mtx_clk_o; |
wire [3:0] ethphy_mii_tx_d; |
wire ethphy_mii_tx_en; |
wire ethphy_mii_tx_err; |
wire mrx_clk_o; |
wire [3:0] mrxd_o; |
wire mrxdv_o; |
wire mrxerr_o; |
wire mcoll_o; |
wire mcrs_o; |
wire ethphy_rst_n; |
wire eth0_mdc_pad_o; |
wire eth0_md_pad_io; |
`endif |
`ifdef XILINX_DDR2 |
`include "xilinx_ddr2_params.v" |
localparam DEVICE_WIDTH = 16; // Memory device data width |
localparam real CLK_PERIOD_NS = CLK_PERIOD / 1000.0; |
localparam real TCYC_200 = 5.0; |
localparam real TPROP_DQS = 0.00; // Delay for DQS signal during Write Operation |
localparam real TPROP_DQS_RD = 0.00; // Delay for DQS signal during Read Operation |
localparam real TPROP_PCB_CTRL = 0.00; // Delay for Address and Ctrl signals |
localparam real TPROP_PCB_DATA = 0.00; // Delay for data signal during Write operation |
localparam real TPROP_PCB_DATA_RD = 0.00; // Delay for data signal during Read operation |
|
wire [DQ_WIDTH-1:0] ddr2_dq_sdram; |
wire [DQS_WIDTH-1:0] ddr2_dqs_sdram; |
wire [DQS_WIDTH-1:0] ddr2_dqs_n_sdram; |
wire [DM_WIDTH-1:0] ddr2_dm_sdram; |
reg [DM_WIDTH-1:0] ddr2_dm_sdram_tmp; |
reg [CLK_WIDTH-1:0] ddr2_ck_sdram; |
reg [CLK_WIDTH-1:0] ddr2_ck_n_sdram; |
reg [ROW_WIDTH-1:0] ddr2_a_sdram; |
reg [BANK_WIDTH-1:0] ddr2_ba_sdram; |
reg ddr2_ras_n_sdram; |
reg ddr2_cas_n_sdram; |
reg ddr2_we_n_sdram; |
reg [CS_WIDTH-1:0] ddr2_cs_n_sdram; |
reg [CKE_WIDTH-1:0] ddr2_cke_sdram; |
reg [ODT_WIDTH-1:0] ddr2_odt_sdram; |
|
wire [DQ_WIDTH-1:0] ddr2_dq_fpga; |
wire [DQS_WIDTH-1:0] ddr2_dqs_fpga; |
wire [DQS_WIDTH-1:0] ddr2_dqs_n_fpga; |
wire [DM_WIDTH-1:0] ddr2_dm_fpga; |
wire [CLK_WIDTH-1:0] ddr2_ck_fpga; |
wire [CLK_WIDTH-1:0] ddr2_ck_n_fpga; |
wire [ROW_WIDTH-1:0] ddr2_a_fpga; |
wire [BANK_WIDTH-1:0] ddr2_ba_fpga; |
wire ddr2_ras_n_fpga; |
wire ddr2_cas_n_fpga; |
wire ddr2_we_n_fpga; |
wire [CS_WIDTH-1:0] ddr2_cs_n_fpga; |
wire [CKE_WIDTH-1:0] ddr2_cke_fpga; |
wire [ODT_WIDTH-1:0] ddr2_odt_fpga; |
`endif |
`ifdef XILINX_SSRAM |
wire sram_clk; |
wire sram_clk_fb; |
wire sram_adv_ld_n; |
wire [3:0] sram_bw; |
wire sram_cen; |
wire [21:1] sram_flash_addr; |
wire [31:0] sram_flash_data; |
wire sram_flash_oe_n; |
wire sram_flash_we_n; |
wire sram_mode; |
`endif |
|
orpsoc_top dut |
( |
`ifdef JTAG_DEBUG |
.tms_pad_i (tms_pad_i), |
.tck_pad_i (tck_pad_i), |
.tdi_pad_i (tdi_pad_i), |
.tdo_pad_o (tdo_pad_o), |
`endif |
`ifdef XILINX_DDR2 |
.ddr2_a (ddr2_a_fpga), |
.ddr2_ba (ddr2_ba_fpga), |
.ddr2_ras_n (ddr2_ras_n_fpga), |
.ddr2_cas_n (ddr2_cas_n_fpga), |
.ddr2_we_n (ddr2_we_n_fpga), |
.ddr2_cs_n (ddr2_cs_n_fpga), |
.ddr2_odt (ddr2_odt_fpga), |
.ddr2_cke (ddr2_cke_fpga), |
.ddr2_dm (ddr2_dm_fpga), |
.ddr2_ck (ddr2_ck_fpga), |
.ddr2_ck_n (ddr2_ck_n_fpga), |
.ddr2_dq (ddr2_dq_fpga), |
.ddr2_dqs (ddr2_dqs_fpga), |
.ddr2_dqs_n (ddr2_dqs_n_fpga), |
`endif |
`ifdef XILINX_SSRAM |
.sram_clk (sram_clk), |
.sram_flash_addr (sram_flash_addr), |
.sram_cen (sram_cen), |
.sram_flash_oe_n (sram_flash_oe_n), |
.sram_flash_we_n (sram_flash_we_n), |
.sram_bw (sram_bw), |
.sram_adv_ld_n (sram_adv_ld_n), |
.sram_mode (sram_mode), |
.sram_clk_fb (sram_clk_fb), |
.sram_flash_data (sram_flash_data), |
`endif |
`ifdef UART0 |
.uart0_stx_pad_o (uart0_stx_pad_o), |
.uart0_srx_pad_i (uart0_srx_pad_i), |
.uart0_stx_expheader_pad_o (uart0_stx_pad_o), |
.uart0_srx_expheader_pad_i (uart0_srx_pad_i), |
`endif |
`ifdef SPI0 |
.spi0_sck_o (spi0_sck_o), |
.spi0_mosi_o (spi0_mosi_o), |
.spi0_miso_i (spi0_miso_i), |
.spi0_ss_o (spi0_ss_o), |
`endif |
`ifdef I2C0 |
.i2c0_sda_io (i2c_sda), |
.i2c0_scl_io (i2c_scl), |
`endif |
`ifdef I2C1 |
.i2c1_sda_io (i2c_sda), |
.i2c1_scl_io (i2c_scl), |
`endif |
`ifdef GPIO0 |
.gpio0_io (gpio0_io), |
`endif |
`ifdef ETH0 |
.eth0_tx_clk (mtx_clk_o), |
.eth0_tx_data (ethphy_mii_tx_d), |
.eth0_tx_en (ethphy_mii_tx_en), |
.eth0_tx_er (ethphy_mii_tx_err), |
.eth0_rx_clk (mrx_clk_o), |
.eth0_rx_data (mrxd_o), |
.eth0_dv (mrxdv_o), |
.eth0_rx_er (mrxerr_o), |
.eth0_col (mcoll_o), |
.eth0_crs (mcrs_o), |
.eth0_rst_n_o (ethphy_rst_n), |
.eth0_mdc_pad_o (eth0_mdc_pad_o), |
.eth0_md_pad_io (eth0_md_pad_io), |
`endif // `ifdef ETH0 |
|
.sys_clk_in_p (clk_p), |
.sys_clk_in_n (clk_n), |
|
.rst_n_pad_i (rst_n) |
); |
|
// |
// Instantiate OR1200 monitor |
// |
or1200_monitor monitor(); |
|
`ifndef SIM_QUIET |
`define CPU_ic_top or1200_ic_top |
`define CPU_dc_top or1200_dc_top |
wire ic_en = orpsoc_testbench.dut.or1200_top0.or1200_ic_top.ic_en; |
always @(posedge ic_en) |
$display("Or1200 IC enabled at %t", $time); |
|
wire dc_en = orpsoc_testbench.dut.or1200_top0.or1200_dc_top.dc_en; |
always @(posedge dc_en) |
$display("Or1200 DC enabled at %t", $time); |
`endif |
|
|
`ifdef JTAG_DEBUG |
`ifdef VPI_DEBUG |
// Debugging interface |
vpi_debug_module vpi_dbg |
( |
.tms(tms_pad_i), |
.tck(tck_pad_i), |
.tdi(tdi_pad_i), |
.tdo(tdo_pad_o) |
); |
`else |
// If no VPI debugging, tie off JTAG inputs |
assign tdi_pad_i = 1; |
assign tck_pad_i = 0; |
assign tms_pad_i = 1; |
`endif // !`ifdef VPI_DEBUG_ENABLE |
`endif // `ifdef JTAG_DEBUG |
|
`ifdef SPI0 |
// SPI flash memory - M25P16 compatible SPI protocol |
AT26DFxxx spi0_flash |
(// Outputs |
.SO (spi0_miso_i), |
// Inputs |
.CSB (spi0_ss_o), |
.SCK (spi0_sck_o), |
.SI (spi0_mosi_o), |
.WPB (1'b1) |
); |
`endif // `ifdef SPI0 |
|
`ifdef ETH0 |
|
/* TX/RXes packets and checks them, enabled when ethernet MAC is */ |
`include "eth_stim.v" |
|
eth_phy eth_phy0 |
( |
// Outputs |
.mtx_clk_o (mtx_clk_o), |
.mrx_clk_o (mrx_clk_o), |
.mrxd_o (mrxd_o[3:0]), |
.mrxdv_o (mrxdv_o), |
.mrxerr_o (mrxerr_o), |
.mcoll_o (mcoll_o), |
.mcrs_o (mcrs_o), |
.link_o (), |
.speed_o (), |
.duplex_o (), |
.smii_clk_i (1'b0), |
.smii_sync_i (1'b0), |
.smii_rx_o (), |
// Inouts |
.md_io (eth0_md_pad_io), |
// Inputs |
`ifndef ETH0_PHY_RST |
// If no reset out from the design, hook up to the board's active low rst |
.m_rst_n_i (rst_n), |
`else |
.m_rst_n_i (ethphy_rst_n), |
`endif |
.mtxd_i (ethphy_mii_tx_d[3:0]), |
.mtxen_i (ethphy_mii_tx_en), |
.mtxerr_i (ethphy_mii_tx_err), |
.mdc_i (eth0_mdc_pad_o)); |
|
`endif // `ifdef ETH0 |
|
`ifdef XILINX_SSRAM |
wire [18:0] sram_a; |
wire [3:0] dqp; |
|
assign sram_a[18:0] = sram_flash_addr[19:1]; |
wire sram_ce1b, sram_ce2, sram_ce3b; |
assign sram_ce1b = 1'b0; |
assign sram_ce2 = 1'b1; |
assign sram_ce3b = 1'b0; |
assign sram_clk_fb = sram_clk; |
|
cy7c1354 ssram0 |
( |
// Inouts |
// This model puts each parity bit after each byte, but the ML501's part |
// doesn't, so we wire up the data bus like so. |
.d ({dqp[3],sram_flash_data[31:24], |
dqp[2],sram_flash_data[23:16], |
dqp[1],sram_flash_data[15:8], |
dqp[0],sram_flash_data[7:0]}), |
// Inputs |
.clk (sram_clk), |
.we_b (sram_flash_we_n), |
.adv_lb (sram_adv_ld_n), |
.ce1b (sram_ce1b), |
.ce2 (sram_ce2), |
.ce3b (sram_ce3b), |
.oeb (sram_flash_oe_n), |
.cenb (sram_cen), |
.mode (sram_mode), |
.bws (sram_bw), |
.a (sram_a)); |
`endif |
|
`ifdef XILINX_DDR2 |
`ifndef GATE_SIM |
defparam dut.xilinx_ddr2_0.xilinx_ddr2_if0.ddr2_mig0.SIM_ONLY = 1; |
`endif |
|
always @( * ) begin |
ddr2_ck_sdram <= #(TPROP_PCB_CTRL) ddr2_ck_fpga; |
ddr2_ck_n_sdram <= #(TPROP_PCB_CTRL) ddr2_ck_n_fpga; |
ddr2_a_sdram <= #(TPROP_PCB_CTRL) ddr2_a_fpga; |
ddr2_ba_sdram <= #(TPROP_PCB_CTRL) ddr2_ba_fpga; |
ddr2_ras_n_sdram <= #(TPROP_PCB_CTRL) ddr2_ras_n_fpga; |
ddr2_cas_n_sdram <= #(TPROP_PCB_CTRL) ddr2_cas_n_fpga; |
ddr2_we_n_sdram <= #(TPROP_PCB_CTRL) ddr2_we_n_fpga; |
ddr2_cs_n_sdram <= #(TPROP_PCB_CTRL) ddr2_cs_n_fpga; |
ddr2_cke_sdram <= #(TPROP_PCB_CTRL) ddr2_cke_fpga; |
ddr2_odt_sdram <= #(TPROP_PCB_CTRL) ddr2_odt_fpga; |
ddr2_dm_sdram_tmp <= #(TPROP_PCB_DATA) ddr2_dm_fpga;//DM signal generation |
end // always @ ( * ) |
|
// Model delays on bi-directional BUS |
genvar dqwd; |
generate |
for (dqwd = 0;dqwd < DQ_WIDTH;dqwd = dqwd+1) begin : dq_delay |
wiredelay # |
( |
.Delay_g (TPROP_PCB_DATA), |
.Delay_rd (TPROP_PCB_DATA_RD) |
) |
u_delay_dq |
( |
.A (ddr2_dq_fpga[dqwd]), |
.B (ddr2_dq_sdram[dqwd]), |
.reset (rst_n) |
); |
end |
endgenerate |
|
genvar dqswd; |
generate |
for (dqswd = 0;dqswd < DQS_WIDTH;dqswd = dqswd+1) begin : dqs_delay |
wiredelay # |
( |
.Delay_g (TPROP_DQS), |
.Delay_rd (TPROP_DQS_RD) |
) |
u_delay_dqs |
( |
.A (ddr2_dqs_fpga[dqswd]), |
.B (ddr2_dqs_sdram[dqswd]), |
.reset (rst_n) |
); |
|
wiredelay # |
( |
.Delay_g (TPROP_DQS), |
.Delay_rd (TPROP_DQS_RD) |
) |
u_delay_dqs_n |
( |
.A (ddr2_dqs_n_fpga[dqswd]), |
.B (ddr2_dqs_n_sdram[dqswd]), |
.reset (rst_n) |
); |
end |
endgenerate |
|
assign ddr2_dm_sdram = ddr2_dm_sdram_tmp; |
parameter NUM_PROGRAM_WORDS=1048576; |
integer ram_ptr, program_word_ptr, k; |
reg [31:0] tmp_program_word; |
reg [31:0] program_array [0:NUM_PROGRAM_WORDS-1]; // 1M words = 4MB |
reg [8*16-1:0] ddr2_ram_mem_line; //8*16-bits= 8 shorts (half-words) |
genvar i, j; |
generate |
// if the data width is multiple of 16 |
for(j = 0; j < CS_NUM; j = j+1) begin : gen_cs // Loop of 1 |
for(i = 0; i < DQS_WIDTH/2; i = i+1) begin : gen // Loop of 4 (DQS_WIDTH=8) |
initial |
begin |
|
`ifdef PRELOAD_RAM |
`include "ddr2_model_preload.v" |
`endif |
ddr2_model u_mem0 |
( |
.ck (ddr2_ck_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
.ck_n (ddr2_ck_n_sdram[CLK_WIDTH*i/DQS_WIDTH]), |
.cke (ddr2_cke_sdram[j]), |
.cs_n (ddr2_cs_n_sdram[CS_WIDTH*i/DQS_WIDTH]), |
.ras_n (ddr2_ras_n_sdram), |
.cas_n (ddr2_cas_n_sdram), |
.we_n (ddr2_we_n_sdram), |
.dm_rdqs (ddr2_dm_sdram[(2*(i+1))-1 : i*2]), |
.ba (ddr2_ba_sdram), |
.addr (ddr2_a_sdram), |
.dq (ddr2_dq_sdram[(16*(i+1))-1 : i*16]), |
.dqs (ddr2_dqs_sdram[(2*(i+1))-1 : i*2]), |
.dqs_n (ddr2_dqs_n_sdram[(2*(i+1))-1 : i*2]), |
.rdqs_n (), |
.odt (ddr2_odt_sdram[ODT_WIDTH*i/DQS_WIDTH]) |
); |
end |
end |
endgenerate |
|
`endif |
|
|
`ifdef VCD |
reg vcd_go = 0; |
always @(vcd_go) |
begin |
|
`ifdef VCD_DELAY |
#(`VCD_DELAY); |
`endif |
|
// Delay by x insns |
`ifdef VCD_DELAY_INSNS |
#10; // Delay until after the value becomes valid |
while (monitor.insns < `VCD_DELAY_INSNS) |
@(posedge clk); |
`endif |
|
`ifdef SIMULATOR_MODELSIM |
// Modelsim can GZip VCDs on the fly if given in the suffix |
`define VCD_SUFFIX ".vcd.gz" |
`else |
`define VCD_SUFFIX ".vcd" |
`endif |
|
`ifndef SIM_QUIET |
$display("* VCD in %s\n", {"../out/",`TEST_NAME_STRING,`VCD_SUFFIX}); |
`endif |
$dumpfile({"../out/",`TEST_NAME_STRING,`VCD_SUFFIX}); |
`ifndef VCD_DEPTH |
`define VCD_DEPTH 0 |
`endif |
$dumpvars(`VCD_DEPTH); |
|
end |
`endif // `ifdef VCD |
|
initial |
begin |
`ifndef SIM_QUIET |
$display("\n* Starting simulation of design RTL.\n* Test: %s\n", |
`TEST_NAME_STRING ); |
`endif |
|
`ifdef VCD |
vcd_go = 1; |
`endif |
|
end // initial begin |
|
`ifdef END_TIME |
initial begin |
#(`END_TIME); |
`ifndef SIM_QUIET |
$display("* Finish simulation due to END_TIME being set at %t", $time); |
`endif |
$finish; |
end |
`endif |
|
`ifdef END_INSNS |
initial begin |
#10 |
while (monitor.insns < `END_INSNS) |
@(posedge clk); |
`ifndef SIM_QUIET |
$display("* Finish simulation due to END_INSNS count (%d) reached at %t", |
`END_INSNS, $time); |
`endif |
$finish; |
end |
`endif |
|
`ifdef UART0 |
// |
// UART0 decoder |
// |
uart_decoder |
#( |
.uart_baudrate_period_ns(8680) // 115200 baud = period 8.68uS |
) |
uart0_decoder |
( |
.clk(clk), |
.uart_tx(uart0_stx_pad_o) |
); |
|
// Loopback UART lines |
assign uart0_srx_pad_i = uart0_stx_pad_o; |
|
`endif // `ifdef UART0 |
|
endmodule // orpsoc_testbench |
|
// Local Variables: |
// verilog-library-directories:("." "../../rtl/verilog/orpsoc_top") |
// verilog-library-files:() |
// verilog-library-extensions:(".v" ".h") |
// End: |
|