diff options
author | jcorgan | 2008-09-08 01:00:12 +0000 |
---|---|---|
committer | jcorgan | 2008-09-08 01:00:12 +0000 |
commit | e0fcbaee124d3e8c4c11bdda662f88e082352058 (patch) | |
tree | a51ef1c8b949681f45e5664478e8515065cfff5b /usrp2/fpga/eth | |
parent | c86f6c23c6883f73d953d64c28ab42cedb77e4d7 (diff) | |
download | gnuradio-e0fcbaee124d3e8c4c11bdda662f88e082352058.tar.gz gnuradio-e0fcbaee124d3e8c4c11bdda662f88e082352058.tar.bz2 gnuradio-e0fcbaee124d3e8c4c11bdda662f88e082352058.zip |
Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top-level components. Trunk passes distcheck with mb-gcc installed, but currently not without them. The key issue is that when mb-gcc is not installed, the build system skips over the usrp2/firmware directory, and the firmware include files don't get put into the dist tarball. But we can't do the usual DIST_SUBDIRS method as the firmware is a subpackage.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9528 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'usrp2/fpga/eth')
63 files changed, 15175 insertions, 0 deletions
diff --git a/usrp2/fpga/eth/bench/verilog/100m.scr b/usrp2/fpga/eth/bench/verilog/100m.scr new file mode 100644 index 000000000..0dd59b894 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/100m.scr @@ -0,0 +1,38 @@ +// This tests just runs a few packets at 10/100 Mbps and 1 Gbps instead of only the usual 1 Gbps
+
+// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps for a starter
+01 00 22 00 04
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+// Transmit a 1000-byte frame 1 time - and expect it to be received again!
+20 03 E8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Set speed to 100 Mbps - this is 10x slower!
+01 00 22 00 02
+
+// Transmit a 1000-byte frame 1 time - and expect it to be received again!
+20 03 E8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Set speed to 10 Mbps - this is yet another 10x slower!
+01 00 22 00 01
+
+// Transmit a 1000-byte frame 1 time - and expect it to be received again!
+20 03 E8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Halt
+FF
diff --git a/usrp2/fpga/eth/bench/verilog/Phy_sim.v b/usrp2/fpga/eth/bench/verilog/Phy_sim.v new file mode 100644 index 000000000..f51ddbd82 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/Phy_sim.v @@ -0,0 +1,113 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// Phy_sim.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: Phy_sim.v,v $
+// Revision 1.3 2006/11/17 17:53:07 maverickist
+// no message
+//
+// Revision 1.2 2006/01/19 14:07:50 maverickist
+// verification is complete.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+`timescale 1ns/100ps
+
+module Phy_sim(
+ input Gtx_clk, // Used only in GMII mode
+ output Rx_clk,
+ output Tx_clk, // Used only in MII mode
+ input Tx_er,
+ input Tx_en,
+ input [7:0] Txd,
+ output Rx_er,
+ output Rx_dv,
+ output [7:0] Rxd,
+ output Crs,
+ output Col,
+ input [2:0] Speed,
+ input Done
+);
+
+//////////////////////////////////////////////////////////////////////
+// this file used to simulate Phy.
+// generate clk and loop the Tx data to Rx data
+// full duplex mode can be verified on loop mode.
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+// internal signals
+//////////////////////////////////////////////////////////////////////
+reg Clk_25m; // Used for 100 Mbps mode
+reg Clk_2_5m; // Used for 10 Mbps mode
+
+//wire Rx_clk;
+//wire Tx_clk; // Used only in MII mode
+
+ initial
+ begin
+ #10;
+ while ( !Done )
+ begin
+ #20 Clk_25m = 0;
+ #20 Clk_25m = 1;
+ end
+ end
+
+ initial
+ begin
+ #10;
+ while ( !Done )
+ begin
+ #200 Clk_2_5m = 0;
+ #200 Clk_2_5m = 1;
+ end
+ end
+
+ assign Rx_clk = Speed[2] ? Gtx_clk : Speed[1] ? Clk_25m : Speed[0] ? Clk_2_5m : 0;
+ assign Tx_clk = Speed[2] ? Gtx_clk : Speed[1] ? Clk_25m : Speed[0] ? Clk_2_5m : 0;
+
+ assign Rx_dv = Tx_en;
+ assign Rxd = Txd;
+ assign Rx_er = Tx_er;
+ assign Crs = Tx_en;
+ assign Col = 0;
+
+endmodule
diff --git a/usrp2/fpga/eth/bench/verilog/User_int_sim.v b/usrp2/fpga/eth/bench/verilog/User_int_sim.v new file mode 100644 index 000000000..3f4aa249b --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/User_int_sim.v @@ -0,0 +1,230 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// User_input_sim.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: User_int_sim.v,v $
+// Revision 1.3 2006/11/17 17:53:07 maverickist
+// no message
+//
+// Revision 1.2 2006/01/19 14:07:50 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/13 12:15:35 Administrator
+// no message
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+module User_int_sim (
+ Reset,
+ Clk_user,
+ CPU_init_end,
+
+ Rx_mac_ra,
+ Rx_mac_rd,
+ Rx_mac_data,
+ Rx_mac_BE,
+ Rx_mac_pa,
+ Rx_mac_sop,
+ Rx_mac_eop,
+
+ Tx_mac_wa,
+ Tx_mac_wr,
+ Tx_mac_data,
+ Tx_mac_BE,
+ Tx_mac_sop,
+ Tx_mac_eop
+);
+
+ input Reset;
+ input Clk_user;
+ input CPU_init_end;
+
+ input Rx_mac_ra;
+ output Rx_mac_rd;
+ input [31:0] Rx_mac_data;
+ input [1:0] Rx_mac_BE;
+ input Rx_mac_pa;
+ input Rx_mac_sop;
+ input Rx_mac_eop;
+
+ input Tx_mac_wa;
+ output reg Tx_mac_wr;
+ output reg [31:0] Tx_mac_data;
+ output reg [1:0] Tx_mac_BE; // Big endian
+ output reg Tx_mac_sop;
+ output reg Tx_mac_eop;
+
+//////////////////////////////////////////////////////////////////////
+// Internal signals
+//////////////////////////////////////////////////////////////////////
+
+ reg [4:0] operation;
+ reg [31:0] data;
+ reg Rx_mac_rd;
+ reg Start_tran;
+
+//////////////////////////////////////////////////////////////////////
+//generate Tx user data
+//////////////////////////////////////////////////////////////////////
+
+ initial
+ begin
+ operation = 0;
+ data = 0;
+ end
+
+ task SendPacket;
+ input [15:0] Length;
+ input [7:0] StartByte;
+
+ reg [15:0] Counter;
+ reg [7:0] TxData;
+
+ begin
+ Counter=Length;
+ TxData = StartByte;
+ Tx_mac_sop = 1; // First time
+ while ( Counter>0 )
+ begin
+ while ( !Tx_mac_wa )
+ begin
+ Tx_mac_wr = 0;
+ @( posedge Clk_user );
+ end
+
+ Tx_mac_data[31:24] = TxData;
+ Tx_mac_data[23:16] = TxData+1;
+ Tx_mac_data[15:8] = TxData+2;
+ Tx_mac_data[ 7:0] = TxData+3;
+ TxData = TxData+4;
+ if ( Counter<=4 )
+ begin
+ // Indicate how many bytes are valid
+ if ( Counter==4 )
+ Tx_mac_BE = 2'b00;
+ else
+ Tx_mac_BE = Counter;
+ Tx_mac_eop = 1;
+ end
+ Tx_mac_wr = 1;
+
+ if ( Counter >= 4 )
+ Counter = Counter - 4;
+ else
+ Counter = 0;
+ @( posedge Clk_user );
+ Tx_mac_sop = 0;
+ end
+
+ Tx_mac_eop = 0;
+ Tx_mac_wr = 0;
+ Tx_mac_data = 32'h0;
+ Tx_mac_BE = 2'b00;
+ end
+ endtask
+
+ always @( posedge Clk_user or posedge Reset )
+ if (Reset)
+ Start_tran <= 0;
+ else if (Tx_mac_eop && !Tx_mac_wa)
+ Start_tran <= 0;
+ else if (Tx_mac_wa)
+ Start_tran <= 1;
+
+ always @(posedge Clk_user)
+ if (Tx_mac_wa && CPU_init_end)
+ /* $ip_32W_gen("../data/config.ini",operation,data); */
+ ;
+ else
+ begin
+ operation <= 0;
+ data <= 0;
+ end
+
+ initial
+ begin
+ Tx_mac_sop = 0;
+ Tx_mac_eop = 0;
+ Tx_mac_wr = 0;
+ Tx_mac_data = 32'h0;
+ Tx_mac_BE = 2'b00;
+
+ #100;
+ while ( Reset )
+ @( posedge Clk_user );
+
+ @( posedge Clk_user );
+
+ while ( !CPU_init_end )
+ @( posedge Clk_user );
+
+ SendPacket( 64, 8'h11 );
+ repeat( 20 )
+ @( posedge Clk_user );
+ SendPacket( 1500, 8'h12 );
+
+ end
+
+// assign Tx_mac_data = data;
+// assign Tx_mac_wr = operation[4];
+// assign Tx_mac_sop = operation[3];
+// assign Tx_mac_eop = operation[2];
+// assign Tx_mac_BE = operation[1:0];
+
+//////////////////////////////////////////////////////////////////////
+//verify Rx user data
+//////////////////////////////////////////////////////////////////////
+
+ always @ (posedge Clk_user or posedge Reset)
+ if (Reset)
+ Rx_mac_rd <= 0;
+ else if (Rx_mac_ra)
+ Rx_mac_rd <= 1;
+ else
+ Rx_mac_rd <= 0;
+
+ always @ (posedge Clk_user )
+ if (Rx_mac_pa)
+ /* $ip_32W_check( Rx_mac_data,
+ {Rx_mac_sop,Rx_mac_eop,Rx_mac_eop?Rx_mac_BE:2'b0});
+ */
+ ;
+
+endmodule
diff --git a/usrp2/fpga/eth/bench/verilog/error.scr b/usrp2/fpga/eth/bench/verilog/error.scr new file mode 100644 index 000000000..af42634a8 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/error.scr @@ -0,0 +1,146 @@ +// This tests sends 5 packets, injecting a bit error in two of them
+// to verify the Rx CRC check works. The corresponding RMON statistics
+// counter is finally checked to verify that the error was registered
+
+// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+//--- Packets #0 & 1 --------------------------------------------------------
+
+// Transmit a 200-byte frame 1 time - and expect it to be received again!
+20 00 C8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Transmit a 200-byte frame 1 time - but expect to receive it with error!
+25 00 C8 00 01
+
+// Inject a single bit error in the packet (data bit 0) - this will cause a CRC error
+23 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+//--- Packets #2 & 3 --------------------------------------------------------
+
+// Transmit a 200-byte frame 1 time - and expect it to be received again!
+20 00 C8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Transmit a 200-byte frame 1 time - but expect to receive it with error!
+25 00 C8 00 01
+
+// Inject a single bit error in the packet (data bit 7) - this will cause a CRC error
+23 00 80
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+//--- Packets #4 & 5 --------------------------------------------------------
+
+// Transmit a 200-byte frame 1 time - and expect it to be received again!
+20 00 C8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Transmit a 200-byte frame 1 time - but don't expect it to be received again!
+21 00 C8 00 01
+
+// Inject a single bit error in the packet (RxEn) - this will cause a packet discard!
+// (because it happens early in the packet)
+23 01 00
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+//--- Packets #6 & 7 --------------------------------------------------------
+
+// Transmit a 200-byte frame 1 time - and expect it to be received again!
+20 00 C8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Transmit a 200-byte frame 1 time - but don't expect it to be received again!
+21 00 C8 00 01
+
+// Inject a single bit error in the packet (RxEr)
+23 02 00
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+//--- Packet #8 -------------------------------------------------------------
+
+// Transmit a 200-byte frame 1 time - and expect it to be received again!
+20 00 C8 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+//---------------------------------------------------------------------------
+
+// Set CPU_rd_addr to address RxCRCErrCounter
+01 00 1C 00 05
+
+// Assert CPU_rd_apply
+01 00 1D 00 01
+
+// Kill a little time while waiting for CPU_rd_grant to assert...
+02 00 1E
+02 00 1E
+02 00 1E
+02 00 1E
+
+// Confirm that CPU_rd_grant is asserted
+03 00 1E 00 01 ff ff
+
+// Read & check low part of RxCRCErrCounter (0x0002)
+03 00 1F 00 02 ff ff
+
+// Read & check high part of RxCRCErrCounter (0x0000)
+03 00 20 00 00 ff ff
+
+// Negate CPU_rd_apply
+01 00 1D 00 00
+
+//---------------------------------------------------------------------------
+
+// Set CPU_rd_addr to address RxTooShortTooLongCounter
+01 00 1C 00 07
+
+// Assert CPU_rd_apply
+01 00 1D 00 01
+
+// Kill a little time while waiting for CPU_rd_grant to assert...
+02 00 1E
+02 00 1E
+02 00 1E
+02 00 1E
+
+// Confirm that CPU_rd_grant is asserted
+03 00 1E 00 01 ff ff
+
+// Read & check low part of RxTooShortTooLongCounter (0x0002)
+03 00 1F 00 02 ff ff
+
+// Read & check high part of RxTooShortTooLongCounter (0x0000)
+03 00 20 00 00 ff ff
+
+// Negate CPU_rd_apply
+01 00 1D 00 00
+
+
+// Halt
+FF
diff --git a/usrp2/fpga/eth/bench/verilog/files.lst b/usrp2/fpga/eth/bench/verilog/files.lst new file mode 100644 index 000000000..6175a4d43 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/files.lst @@ -0,0 +1,42 @@ +../../rtl/verilog/MAC_rx/Broadcast_filter.v
+../../rtl/verilog/MAC_rx/CRC_chk.v
+../../rtl/verilog/MAC_rx/MAC_rx_add_chk.v
+../../rtl/verilog/MAC_rx/MAC_rx_ctrl.v
+../../rtl/verilog/MAC_rx/MAC_rx_FF.v
+
+../../rtl/verilog/MAC_tx/CRC_gen.v
+../../rtl/verilog/MAC_tx/flow_ctrl.v
+../../rtl/verilog/MAC_tx/MAC_tx_addr_add.v
+../../rtl/verilog/MAC_tx/MAC_tx_ctrl.v
+../../rtl/verilog/MAC_tx/MAC_tx_FF.v
+../../rtl/verilog/MAC_tx/Ramdon_gen.v
+
+../../rtl/verilog/miim/eth_clockgen.v
+../../rtl/verilog/miim/eth_outputcontrol.v
+../../rtl/verilog/miim/eth_shiftreg.v
+
+../../rtl/verilog/RMON/RMON_addr_gen.v
+../../rtl/verilog/RMON/RMON_ctrl.v
+../../rtl/verilog/RMON/RMON_dpram.v
+
+../../rtl/verilog/TECH/duram.v
+../../rtl/verilog/TECH/eth_clk_div2.v
+../../rtl/verilog/TECH/eth_clk_switch.v
+
+../../rtl/verilog/TECH/xilinx/BUFGMUX.v
+../../rtl/verilog/TECH/xilinx/RAMB16_S36_S36.v
+
+../../rtl/verilog/Clk_ctrl.v
+../../rtl/verilog/eth_miim.v
+../../rtl/verilog/MAC_rx.v
+../../rtl/verilog/MAC_top.v
+../../rtl/verilog/MAC_tx.v
+../../rtl/verilog/Phy_int.v
+../../rtl/verilog/Reg_int.v
+../../rtl/verilog/RMON.v
+
+../../bench/verilog/Phy_sim.v
+../../bench/verilog/User_int_sim.v
+../../bench/verilog/host_sim.v
+../../bench/verilog/xlnx_glbl.v
+../../bench/verilog/tb_top.v
diff --git a/usrp2/fpga/eth/bench/verilog/host_sim.v b/usrp2/fpga/eth/bench/verilog/host_sim.v new file mode 100644 index 000000000..55abb8508 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/host_sim.v @@ -0,0 +1,82 @@ +module host_sim(
+ input Reset,
+ input Clk_reg,
+ output reg CSB,
+ output reg WRB,
+ output reg CPU_init_end,
+ output reg [15:0] CD_in,
+ input [15:0] CD_out,
+ output reg [7:0] CA
+);
+
+////////////////////////////////////////
+
+task CPU_init;
+ begin
+ CA = 0;
+ CD_in = 0;
+ WRB = 1;
+ CSB = 1;
+ end
+endtask
+
+////////////////////////////////////////
+
+task CPU_wr;
+ input [6:0] Addr;
+ input [15:0] Data;
+ begin
+ CA = {Addr,1'b0};
+ CD_in = Data;
+ WRB = 0;
+ CSB = 0;
+ #20;
+ CA = 0;
+ CD_in = 0;
+ WRB = 1;
+ CSB = 1;
+ #20;
+ end
+endtask
+
+/////////////////////////////////////////
+
+task CPU_rd;
+ input [6:0] Addr;
+ begin
+ CA = {Addr,1'b0};
+ WRB = 1;
+ CSB = 0;
+ #20;
+ CA = 0;
+ WRB = 1;
+ CSB = 1;
+ #20;
+ end
+endtask
+
+/////////////////////////////////////////
+
+integer i;
+
+reg [31:0] CPU_data [255:0];
+reg [7:0] write_times;
+reg [7:0] write_add;
+reg [15:0] write_data;
+
+initial
+ begin
+ CPU_init;
+ CPU_init_end=0;
+ //$readmemh("../data/CPU.vec",CPU_data);
+ //{write_times,write_add,write_data}=CPU_data[0];
+ {write_times,write_add,write_data}='b0;
+ #90;
+ for (i=0;i<write_times;i=i+1)
+ begin
+ {write_times,write_add,write_data}=CPU_data[i];
+ CPU_wr(write_add[6:0],write_data);
+ end
+ CPU_init_end=1;
+ end
+endmodule
diff --git a/usrp2/fpga/eth/bench/verilog/icomp.bat b/usrp2/fpga/eth/bench/verilog/icomp.bat new file mode 100644 index 000000000..11e221e08 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/icomp.bat @@ -0,0 +1 @@ +iverilog -I ..\..\rtl\verilog -c files.lst
diff --git a/usrp2/fpga/eth/bench/verilog/isim.bat b/usrp2/fpga/eth/bench/verilog/isim.bat new file mode 100644 index 000000000..e77969659 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/isim.bat @@ -0,0 +1 @@ +vvp a.out %*
diff --git a/usrp2/fpga/eth/bench/verilog/jumbo_err.scr b/usrp2/fpga/eth/bench/verilog/jumbo_err.scr new file mode 100644 index 000000000..b0177f474 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/jumbo_err.scr @@ -0,0 +1,40 @@ +// This test performs transmission & reception of several Jumbo-frame of ~2Kbytes
+// In one of the frames an error is injected to allow analysis of how the
+// MAC Rx interface reacts to errors in long packets
+
+// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+// Transmit a 2049-byte frame 2 times - and expect them to be received again!
+20 08 02 00 02
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Transmit a 2049-byte frame 1 time - but expect to receive it with error!
+25 08 02 00 01
+
+// Delay 256 NOPs to time the error injection to be late in the packet
+0F 01 00
+
+// Inject a single bit error in the packet (data bit 0)
+23 01 00
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Transmit a 2049-byte frame 2 times - and expect them to be received again!
+20 08 01 00 02
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Halt
+FF
diff --git a/usrp2/fpga/eth/bench/verilog/jumbos.scr b/usrp2/fpga/eth/bench/verilog/jumbos.scr new file mode 100644 index 000000000..f48870bd5 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/jumbos.scr @@ -0,0 +1,27 @@ +// This test performs transmission & reception of several Jumbo-frames of ~2Kbytes each
+// At the same time it demonstrates the wire-speed capabilities of the core
+
+// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+// Transmit a 2047-byte frame 3 times - and expect them to be received again!
+20 07 ff 00 03
+// Transmit a 2048-byte frame 3 times - and expect them to be received again!
+20 08 00 00 03
+// Transmit a 2049-byte frame 3 times - and expect them to be received again!
+20 08 01 00 03
+// Transmit a 2050-byte frame 3 times - and expect them to be received again!
+20 08 02 00 03
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Halt
+FF
diff --git a/usrp2/fpga/eth/bench/verilog/mdio.scr b/usrp2/fpga/eth/bench/verilog/mdio.scr new file mode 100644 index 000000000..8ad9969b9 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/mdio.scr @@ -0,0 +1,52 @@ +// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Set MDIO clock (MDC) divider to 4 to speed up test
+01 00 23 00 04
+03 00 23 00 04 ff ff
+
+// Check default (reset) values in new (added) MDIO registers
+//03 00 23 00 64 ff ff
+03 00 24 00 00 ff ff
+03 00 25 00 00 ff ff
+03 00 26 00 00 ff ff
+03 00 27 00 00 ff ff
+03 00 28 00 00 ff ff
+
+// Set RGAD=0x00 (all zeroes), FIAD=0x1f (all ones), check it
+// - these values allows easy recognition in the waveform
+01 00 25 00 1f
+03 00 25 00 1f ff ff
+
+// Now start the read operation by writing a 1 to the MIICOMMAND[1] - RSTAT
+01 00 24 00 02
+03 00 24 00 02 ff ff
+
+// Delay for 768 NOP
+0F 03 00
+
+// Check that the read operation has completed
+03 00 28 00 00 ff ff
+
+// Set RGAD=0x1f (all ones), FIAD=0x00 (all zeroes), check it
+// - these values allows easy recognition in the waveform
+01 00 25 1f 00
+03 00 25 1f 00 ff ff
+// Set MIITX_DATA = 0xAAAA, check it
+01 00 26 AA AA
+03 00 26 AA AA ff ff
+// Check MIISTATUS - must still be zero
+03 00 28 00 00 ff ff
+
+// Now start the write operation by writing a 1 to the MIICOMMAND[2] - WCTRLDATA
+01 00 24 00 04
+03 00 24 00 04 ff ff
+
+// Delay for 768 NOP
+0F 03 00
+
+// Check that the write operation has completed
+03 00 28 00 00 ff ff
diff --git a/usrp2/fpga/eth/bench/verilog/miim_model.v b/usrp2/fpga/eth/bench/verilog/miim_model.v new file mode 100644 index 000000000..936d99a80 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/miim_model.v @@ -0,0 +1,14 @@ + +// Skeleton PHY interface simulator + +module miim_model(input mdc_i, + inout mdio, + input phy_resetn_i, + input phy_clk_i, + output phy_intn_o, + output [2:0] speed_o); + + assign phy_intn_o = 1; // No interrupts + assign speed_o = 3'b100; // 1G mode + +endmodule // miim_model diff --git a/usrp2/fpga/eth/bench/verilog/misc.scr b/usrp2/fpga/eth/bench/verilog/misc.scr new file mode 100644 index 000000000..092362964 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/misc.scr @@ -0,0 +1,92 @@ +// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Write MAC address 12 35 56 78 9A BC to Rx Address buffer
+01 00 10 00 00
+01 00 0f 00 12
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 01
+01 00 0f 00 34
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 02
+01 00 0f 00 56
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 03
+01 00 0f 00 78
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 04
+01 00 0f 00 9A
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 05
+01 00 0f 00 BC
+01 00 11 00 01
+01 00 11 00 00
+
+// Write 1 to register 14, MAC_rx_add_chk_en
+// This turns on the Rx Destination MAC address filter
+01 00 0e 00 01
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+// (i.e. Destination MAC address is 123456789ABC matching the above)
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+// Transmit a 60-byte frame 1 time - and expect it to be received again!
+20 00 3C 00 01
+// Transmit a 61-byte frame 1 time - and expect it to be received again!
+20 00 3D 00 01
+// Transmit a 62-byte frame 1 time - and expect it to be received again!
+20 00 3E 00 01
+// Transmit a 63-byte frame 1 time - and expect it to be received again!
+20 00 3F 00 01
+// Transmit a 64-byte frame 1 time - and expect it to be received again!
+20 00 40 00 01
+
+// Transmit a 500-byte frame 1 time - and expect it to be received again!
+20 01 4C 00 01
+
+// Transmit a 1500-byte frame 1 time - and expect it to be received again!
+20 05 DC 00 01
+
+// Transmit a 1514-byte frame 1 time - and expect it to be received again!
+20 05 EA 00 01
+
+// Transmit a 60-byte frame 3 times - and expect them to be received again!
+20 00 3C 00 03
+// Transmit a 61-byte frame 3 times - and expect them to be received again!
+20 00 3D 00 03
+// Transmit a 62-byte frame 3 times - and expect them to be received again!
+20 00 3E 00 03
+// Transmit a 63-byte frame 3 times - and expect them to be received again!
+20 00 3F 00 03
+// Transmit a 64-byte frame 3 times - and expect them to be received again!
+20 00 40 00 03
+
+// Transmit a 1510-byte frame 1 time - and expect it to be received again!
+20 05 E6 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Change Tx MAC to something different - we won't receive frames with this ID
+10 00 00 00 06 11 22 33 44 55 66
+
+// Transmit a 60 byte frame 3 times - but don't expect them to be received!
+21 00 3C 00 03
+
+//// Change Tx MAC back to 12 34 56 78 9A BC
+10 00 00 00 06 12 34 56 78 9A BC
+
+// Transmit a 60 byte frame 3 times - and expect them to be received again!
+20 00 3C 00 03
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
diff --git a/usrp2/fpga/eth/bench/verilog/pause.scr b/usrp2/fpga/eth/bench/verilog/pause.scr new file mode 100644 index 000000000..be74027e3 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/pause.scr @@ -0,0 +1,45 @@ +// This test demonstrates the ability to transmit a PAUSE frame, and the effect of
+// a PAUSE frame on the receiver
+
+// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+// Set PAUSE quanta to 256 - corresponding to a pause of 256x512 = 128Kb = 16KB
+01 00 03 01 00
+
+// Enable the transmitter to send a PAUSE frame
+01 00 02 00 01
+
+// Enable the transmitter to react to received PAUSE frames
+01 00 0b 00 01
+
+// Expect to receive a PAUSE frame with quanta 256
+24 01 00
+
+// Transmit a 512-byte frame 1 time - and expect it to be received again!
+20 02 00 00 01
+
+// Request the transmission of a PAUSE frame - it will loopback to ourselves and delay
+// further transmission for a period of 16 KB, causing a significant (visible) delay
+// between first and second 512-byte frame!
+01 00 0c 00 01
+
+// - now this second time, we will experience a delay
+// Transmit a 512-byte frame 1 time - and expect it to be received again!
+20 02 00 00 01
+// - and a final 3rd time
+// Transmit a 512-byte frame 1 time - and expect it to be received again!
+20 02 00 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Halt
+FF
diff --git a/usrp2/fpga/eth/bench/verilog/tb_top.v b/usrp2/fpga/eth/bench/verilog/tb_top.v new file mode 100644 index 000000000..e54bc201b --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/tb_top.v @@ -0,0 +1,1057 @@ +`timescale 1 ns / 1 ps
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// tb_top.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: tb_top.v,v $
+// Revision 1.3 2006/01/19 14:07:51 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:13 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+module tb_top;
+
+ //-------------------- Instantiate Xilinx glbl module ----------------------
+ // - this is needed to get ModelSim to work because e.g. I/O buffer models
+ // refer directly to glbl.GTS and similar signals
+
+ wire GSR;
+ wire GTS;
+ xlnx_glbl glbl( .GSR( GSR ), .GTS( GTS ) );
+
+ reg VLOG_ExitSignal = 0;
+ reg Done = 0;
+ reg Error = 0;
+
+ //-------------------------------------------------------------------------
+
+ // System signals
+ wire Reset;
+ reg Clk_125M;
+ reg Clk_user;
+
+ reg RST_I;
+ reg CLK_I;
+ reg STB_I;
+ reg CYC_I;
+ reg [6:0] ADR_I;
+ reg WE_I;
+ reg [15:0] DAT_I;
+ wire [15:0] DAT_O;
+ wire ACK_O;
+
+ // User interface (Rx)
+ wire Rx_mac_ra;
+ reg Rx_mac_rd = 0;
+ wire [31:0] Rx_mac_data;
+ wire [1:0] Rx_mac_BE;
+ wire Rx_mac_pa;
+ wire Rx_mac_sop;
+ wire Rx_mac_err;
+ wire Rx_mac_eop;
+
+ // User interface (Tx)
+ wire Tx_mac_wa;
+ reg Tx_mac_wr = 0;
+ reg [31:0] Tx_mac_data = 32'bx;
+ reg [1:0] Tx_mac_BE = 2'bx;
+ reg Tx_mac_sop = 1'bx;
+ reg Tx_mac_eop = 1'bx;
+
+ // PHY interface (GMII/MII)
+ wire Gtx_clk;
+ wire Rx_clk;
+ wire Tx_clk;
+ wire Tx_er;
+ wire Tx_en;
+ wire [7:0] Txd;
+ wire Rx_er;
+ wire Rx_dv;
+ wire [7:0] Rxd;
+ wire Crs;
+ wire Col;
+
+ // PHY int host interface
+
+ wire Line_loop_en;
+ wire [2:0] Speed;
+
+ // MDIO interface
+ wire Mdio; // MII Management Data In
+ wire Mdc; // MII Management Data Clock
+
+ //-------------------------------------------------------------------------
+
+ // Generate generic reset signal from Wishbone specific one
+ assign Reset = RST_I;
+
+ MAC_top U_MAC_top(
+ // System signals
+ .Clk_125M ( Clk_125M ),
+ .Clk_user ( Clk_user ),
+ .Speed ( Speed ),
+
+ // Wishbone compliant core host interface
+ .RST_I ( RST_I ),
+ .CLK_I ( CLK_I ),
+ .STB_I ( STB_I ),
+ .CYC_I ( CYC_I ),
+ .ADR_I ( ADR_I ),
+ .WE_I ( WE_I ),
+ .DAT_I ( DAT_I ),
+ .DAT_O ( DAT_O ),
+ .ACK_O ( ACK_O ),
+
+ // User (packet) interface
+ .Rx_mac_ra ( Rx_mac_ra ),
+ .Rx_mac_rd ( Rx_mac_rd ),
+ .Rx_mac_data( Rx_mac_data ),
+ .Rx_mac_BE ( Rx_mac_BE ),
+ .Rx_mac_pa ( Rx_mac_pa ),
+ .Rx_mac_sop ( Rx_mac_sop ),
+ .Rx_mac_err ( Rx_mac_err ),
+ .Rx_mac_eop ( Rx_mac_eop ),
+
+ .Tx_mac_wa ( Tx_mac_wa ),
+ .Tx_mac_wr ( Tx_mac_wr ),
+ .Tx_mac_data( Tx_mac_data ),
+ .Tx_mac_BE ( Tx_mac_BE ),
+ .Tx_mac_sop ( Tx_mac_sop ),
+ .Tx_mac_eop ( Tx_mac_eop ),
+
+ // PHY interface (GMII/MII)
+ .Gtx_clk ( Gtx_clk ),
+ .Rx_clk ( Rx_clk ),
+ .Tx_clk ( Tx_clk ),
+ .Tx_er ( Tx_er ),
+ .Tx_en ( Tx_en ),
+ .Txd ( Txd ),
+ .Rx_er ( Rx_er ),
+ .Rx_dv ( Rx_dv ),
+ .Rxd ( Rxd ),
+ .Crs ( Crs ),
+ .Col ( Col ),
+
+ // MDIO interface (to PHY)
+ .Mdio ( Mdio ),
+ .Mdc ( Mdc )
+ );
+
+ reg [15:0] InjectError;
+ reg InjectErrorDone;
+ reg [15:0] TxError;
+ wire Tx_er_Modified;
+ wire Tx_en_Modified;
+ wire [7:0] Txd_Modified;
+
+ Phy_sim U_Phy_sim(
+ .Gtx_clk( Gtx_clk ),
+ .Rx_clk ( Rx_clk ),
+ .Tx_clk ( Tx_clk ),
+ .Tx_er ( Tx_er_Modified ),
+ .Tx_en ( Tx_en_Modified ),
+ .Txd ( Txd_Modified ),
+ .Rx_er ( Rx_er ),
+ .Rx_dv ( Rx_dv ),
+ .Rxd ( Rxd ),
+ .Crs ( Crs ),
+ .Col ( Col ),
+ .Speed ( Speed ),
+ .Done ( Done )
+ );
+
+ integer TxTrackPreAmble;
+
+ always @( posedge Reset or posedge Tx_clk )
+ if ( Reset )
+ TxTrackPreAmble <= 0;
+ else
+ if ( ~Tx_en )
+ TxTrackPreAmble <= 0;
+ else
+ TxTrackPreAmble <= TxTrackPreAmble + 1;
+
+ // Asserted after the Destination MAC address in the packet
+ wire TxInPayload = Tx_en & (TxTrackPreAmble > (7+6));
+ assign Tx_er_Modified = Tx_er ^ ( TxError[9] & TxInPayload );
+ assign Tx_en_Modified = Tx_en ^ ( TxError[8] & TxInPayload );
+ assign Txd_Modified = Txd ^ ( TxError[7:0] & {8{TxInPayload}} );
+
+ always @( posedge Reset or posedge Tx_clk )
+ if ( Reset )
+ begin
+ InjectError <= 0;
+ InjectErrorDone <= 0;
+ TxError <= 'b0;
+ end
+ else
+ if ( InjectError )
+ begin
+ TxError <= InjectError;
+ InjectError <= 0;
+ InjectErrorDone <= TxInPayload;
+ end
+ else if ( TxInPayload || InjectErrorDone )
+ begin
+ TxError <= 8'h00;
+ InjectErrorDone <= 0;
+ end
+
+ //-------------------------------------------------------------------------
+ // Track pause on Tx interface
+
+ reg TxEnSeenOnce;
+ integer TxTrackPause;
+
+ always @( posedge Reset or posedge Tx_clk )
+ if ( Reset )
+ begin
+ TxEnSeenOnce <= 0;
+ TxTrackPause <= 0;
+ end
+ else
+ if ( Tx_en )
+ begin
+ if ( TxEnSeenOnce && (TxTrackPause >= 64) ) // 512 bits
+ $display( "IDLE period on Tx interface ended after %0d Tx clocks (%0d bits, tick ~ %0d)",
+ TxTrackPause,
+ (Speed == 4) ? TxTrackPause*8 : TxTrackPause*4,
+ (Speed == 4) ? TxTrackPause*8/512 : TxTrackPause*4/512 );
+ TxEnSeenOnce <= 1;
+ TxTrackPause <= 0;
+ end
+ else
+ TxTrackPause <= TxTrackPause + 1;
+
+ //-------------------------------------------------------------------------
+ // Host access routines (register read & write)
+ //-------------------------------------------------------------------------
+
+ task HostInit;
+ begin
+ RST_I <= 1;
+
+ STB_I <= 0;
+ CYC_I <= 0;
+ ADR_I <= 'b0;
+ WE_I <= 0;
+ DAT_I <= 'b0;
+
+ #100 RST_I <= 0;
+
+ // Wait a couple of clock edges before continuing to allow
+ // internal logic to get out of reset
+ repeat( 2 )
+ @( posedge CLK_I );
+ end
+ endtask
+
+ task HostWriteReg;
+ input [6:0] Addr;
+ input [15:0] Data;
+ begin
+ @( posedge CLK_I );
+ ADR_I <= Addr;
+ DAT_I <= Data;
+ WE_I <= 1;
+ STB_I <= 1;
+ CYC_I <= 1;
+
+ @( posedge CLK_I );
+
+ while ( ~ACK_O )
+ @( posedge CLK_I );
+
+ STB_I <= 0;
+ CYC_I <= 0;
+ end
+ endtask
+
+ task HostReadReg;
+ input [6:0] Addr;
+ output [15:0] Data;
+ begin
+ @( posedge CLK_I );
+ ADR_I <= Addr;
+ WE_I <= 0;
+ STB_I <= 1;
+ CYC_I <= 1;
+
+ @( posedge CLK_I );
+
+ while ( ~ACK_O )
+ @( posedge CLK_I );
+
+ Data = DAT_O;
+ STB_I <= 0;
+ CYC_I <= 0;
+ end
+ endtask
+
+ //-------------------------------------------------------------------------
+ // User interface access routines (packet Tx and Rx)
+ //-------------------------------------------------------------------------
+
+ `define FIFOSIZE 10000
+
+ integer FIFO_WrPtr = 0;
+ integer FIFO_RdPtr = 0;
+ integer FIFO_ElementCount = 0;
+ reg [35:0] FIFO_Data[0:`FIFOSIZE];
+
+ function FIFO_Empty;
+ input Dummy;
+ begin
+ if ( FIFO_ElementCount > 0 )
+ FIFO_Empty = 0;
+ else
+ FIFO_Empty = 1;
+ end
+ endfunction
+
+ function FIFO_Full;
+ input Dummy;
+ begin
+ if ( FIFO_ElementCount < `FIFOSIZE )
+ FIFO_Full = 0;
+ else
+ FIFO_Full = 1;
+ end
+ endfunction
+
+ task FIFO_Wr;
+ input [35:0] Data;
+
+ begin
+ if ( !FIFO_Full(0) )
+ begin
+ FIFO_Data[ FIFO_WrPtr ] = Data;
+ FIFO_WrPtr = (FIFO_WrPtr + 1) % `FIFOSIZE;
+ FIFO_ElementCount = FIFO_ElementCount + 1;
+ end
+ else
+ begin
+ $display( "ERROR: FIFO_Wr() - FIFO overflow!" );
+ Error = 1;
+ $finish;
+ end
+ end
+ endtask
+
+ task FIFO_Rd;
+ output [35:0] Data;
+
+ begin
+ if ( !FIFO_Empty(0) )
+ begin
+ Data = FIFO_Data[ FIFO_RdPtr ];
+ FIFO_RdPtr = (FIFO_RdPtr + 1) % `FIFOSIZE;
+ FIFO_ElementCount = FIFO_ElementCount - 1;
+ end
+ else
+ begin
+ $display( "ERROR: FIFO_Rd() - Reading from empty FIFO!" );
+ Error = 1;
+ $finish;
+ end
+ end
+ endtask
+
+ //-------------------------------------------------------------------------
+
+ `define TXDATALEN 8000
+ reg [7:0] TxData[0:`TXDATALEN-1];
+ reg [7:0] TxAltData[0:`TXDATALEN-1];
+
+ // By default change payload after Ethernet Header
+ reg [15:0] TxHeaderLength = 14;
+
+ real TxStartTime;
+ integer TxPacketCount = 0;
+ integer TxByteCount;
+
+ task SendPacket;
+ input [15:0] Length;
+ // 0: Don't write to FIFO, 1: Write to FIFO, 2: Write Alternate to FIFO, 3: Write IGNORE to FIFO
+ input [1:0] Wr2FIFO;
+
+ reg [15:0] Counter;
+ integer TxIndex;
+ integer i;
+
+ reg [31:0] Tx_fifo_data;
+
+ begin
+ @( posedge Clk_user ); #1;
+
+ TxPacketCount = TxPacketCount + 1;
+ TxByteCount = TxByteCount + Length;
+
+ Counter=Length;
+ TxIndex = 0;
+ Tx_mac_sop = 1; // First time
+
+ if ( TxStartTime == 0 )
+ TxStartTime = $realtime;
+
+ while ( Counter>0 )
+ begin
+ while ( !Tx_mac_wa )
+ begin
+ Tx_mac_wr = 0;
+ @( posedge Clk_user ); #1;
+ end
+
+ Tx_mac_data[31:24] = TxData[ TxIndex ];
+ Tx_mac_data[23:16] = TxData[ TxIndex+1 ];
+ Tx_mac_data[15:8] = TxData[ TxIndex+2 ];
+ Tx_mac_data[ 7:0] = TxData[ TxIndex+3 ];
+
+ // Default take data from regular tx buffer
+ Tx_fifo_data = Tx_mac_data;
+ if ( Wr2FIFO==2 )
+ begin
+ // Put content of Alternate Tx buffer on Rx expectancy queue
+ if ( (TxIndex+0)<TxHeaderLength )
+ Tx_fifo_data[31:24] = TxAltData[ TxIndex ];
+ if ( (TxIndex+1)<TxHeaderLength )
+ Tx_fifo_data[23:16] = TxAltData[ TxIndex+1 ];
+ if ( (TxIndex+2)<TxHeaderLength )
+ Tx_fifo_data[15:8] = TxAltData[ TxIndex+2 ];
+ if ( (TxIndex+3)<TxHeaderLength )
+ Tx_fifo_data[ 7:0] = TxAltData[ TxIndex+3 ];
+ end
+
+ for ( i=0; i<4; i=i+1 )
+ begin
+ if ( TxIndex >= TxHeaderLength )
+ TxData[ TxIndex ] = TxData[ TxIndex ] + 1;
+ TxIndex = TxIndex+1;
+ end
+
+ if ( Counter<=4 )
+ begin
+ // Indicate how many bytes are valid
+ if ( Counter==4 )
+ Tx_mac_BE = 2'b00;
+ else
+ Tx_mac_BE = Counter;
+ Tx_mac_eop = 1;
+ end
+ else
+ begin
+ Tx_mac_BE = 2'b00;
+ Tx_mac_eop = 0;
+ end
+
+ casez ( Wr2FIFO )
+ 1,
+ 2: FIFO_Wr( { Tx_mac_sop, Tx_mac_eop, Tx_mac_BE, Tx_fifo_data } );
+ 3: // Ignore
+ begin
+ FIFO_Wr( { 2'b11, 2'b00, 32'h00000000 } );
+ Wr2FIFO = 0;
+ end
+ endcase
+
+ Tx_mac_wr = 1;
+
+ if ( Counter >= 4 )
+ Counter = Counter - 4;
+ else
+ Counter = 0;
+ @( posedge Clk_user ); #1;
+ Tx_mac_sop = 0;
+ end
+
+ Tx_mac_sop = 1'bx;
+ Tx_mac_eop = 1'bx;
+ Tx_mac_wr = 0;
+ Tx_mac_data = 32'bx;
+ Tx_mac_BE = 2'bx;
+ end
+ endtask
+
+ //-------------------------------------------------------------------------
+
+ reg Negate_Rx_mac_rd;
+
+ always @( posedge Clk_user or posedge Reset )
+ if ( Reset )
+ Rx_mac_rd <= 0;
+ else if ( Rx_mac_ra & ~Negate_Rx_mac_rd )
+ Rx_mac_rd <= 1;
+ else
+ Rx_mac_rd <= 0;
+
+ real RxStartTime;
+ integer RxPacketCount;
+ integer RxByteCount;
+
+ reg InPacket;
+ integer RxPacketLength;
+ reg IgnoreUntilNextERR;
+
+ always @( posedge Clk_user or posedge Reset )
+ if ( Reset )
+ begin
+ InPacket = 0;
+ RxPacketCount = 0;
+ Negate_Rx_mac_rd <= 0;
+ IgnoreUntilNextERR = 0;
+ end
+ else
+ begin
+ Negate_Rx_mac_rd <= 0;
+
+ if ( Rx_mac_pa )
+ begin : RxWord
+ reg [35:0] RxData;
+ reg [35:0] Expected;
+ reg [35:0] Mask;
+
+ RxData = { Rx_mac_sop, Rx_mac_eop, Rx_mac_BE, Rx_mac_data };
+ casez ( Rx_mac_BE )
+ 2'b01: Mask = 36'hfff000000;
+ 2'b10: Mask = 36'hfffff0000;
+ 2'b11: Mask = 36'hfffffff00;
+ default: Mask = 36'hfffffffff;
+ endcase
+
+ // Retrieve expected packet data
+
+ if ( !IgnoreUntilNextERR )
+ begin
+ FIFO_Rd( Expected );
+ if ( Expected[35] & Expected[34] )
+ begin
+ // Both SOP & EOP are asserted in expectancy data
+ // - this means that we should ignore all data received until next EOP
+ $display( "The payload of this packet will be IGNORED - and an ERROR must be signalled!" );
+ IgnoreUntilNextERR = 1;
+ end
+ end
+ if ( IgnoreUntilNextERR )
+ Mask = 36'h000000000;
+
+ //$display( "DEBUG: RxData=0x%0x, Expected=0x%0x", RxData, Expected );
+
+ if ( (RxData & Mask) !== (Expected & Mask) )
+ begin
+ $display( "ERROR: Receiving unexpected packet data: Got 0x%0x, expected 0x%0x (Mask=0x%0x)",
+ RxData, Expected, Mask );
+ Error = 1;
+ end
+
+ if ( InPacket )
+ begin
+ if ( Rx_mac_eop )
+ begin
+ // Ensure Rx_mac_rd is negated for one clock
+ Negate_Rx_mac_rd <= 1;
+ if ( Rx_mac_BE==2'b00 )
+ RxPacketLength = RxPacketLength + 4;
+ else
+ RxPacketLength = RxPacketLength + Rx_mac_BE;
+ $display( "Rx packet #%0d of length %0d ends",
+ RxPacketCount,
+ RxPacketLength );
+ RxPacketCount = RxPacketCount + 1;
+ RxByteCount = RxByteCount + RxPacketLength;
+ InPacket = 0;
+ end
+ else
+ RxPacketLength = RxPacketLength + 4;
+ end
+ else
+ begin
+ if ( Rx_mac_sop )
+ begin
+ RxPacketLength = 4;
+ $display( "Rx packet #%0d begins: 0x%08x", RxPacketCount, Rx_mac_data );
+ InPacket = 1;
+ if ( RxStartTime == 0 )
+ RxStartTime = $realtime;
+ end
+ else
+ begin
+ $display( "ERROR: Unexpectedly reading from Rx FIFO while not receiving a packet!" );
+ Error = 1;
+ end
+ end
+
+ if ( Rx_mac_err )
+ begin
+ if ( !Rx_mac_eop )
+ begin
+ $display( "ERROR: Rx_mac_err was asserted without Rx_mac_eop also being asserted!" );
+ Error = 1;
+ end
+ if ( IgnoreUntilNextERR )
+ $display( "Info: Rx_mac_err was asserted as expected!" );
+ else
+ begin
+ $display( "ERROR: Rx_mac_err was unexpectedly asserted!" );
+ Error = 1;
+ end
+ IgnoreUntilNextERR = 0;
+ end
+ end
+ end
+
+ //-------------------------------------------------------------------------
+ // Script handling
+ //-------------------------------------------------------------------------
+
+ integer PC;
+
+ task ScriptWriteReg;
+ input [15:0] Addr;
+ input [15:0] Data;
+
+ begin
+ $display( "WriteReg( 0x%04x, 0x%04x )", Addr, Data );
+ HostWriteReg( Addr, Data );
+ end
+ endtask
+
+ task ScriptReadReg;
+ input [15:0] Addr;
+
+ reg [15:0] Data;
+
+ begin
+ $write( "ReadReg( 0x%04x ): ", Addr );
+ HostReadReg( Addr, Data );
+ $display( "0x%04x", Data );
+ end
+ endtask
+
+ task ScriptReadRegAndMatch;
+ input [15:0] Addr;
+ input [15:0] Data;
+ input [15:0] Mask;
+
+ reg [15:0] Read;
+
+ begin
+ $write( "ReadRegAndMatch( 0x%04x, 0x%04x, 0x%04x ): ", Addr, Data, Mask );
+
+ HostReadReg( Addr, Read );
+ $display( "0x%04x, masked=0x%04x", Read, Read & Mask );
+
+ if ( Data !== (Read & Mask) )
+ begin
+ $display( "Error: Unexpected data read" );
+ Error = 1;
+ end
+ end
+ endtask
+
+ integer RxExpectPacketCount = 0;
+
+ task ScriptSendPacket;
+ input [15:0] Length;
+ // 0: Don't receive, 1: Receive & match, 2: Receive & match alternate, 3: Receive & ignore
+ input [1:0] ExpectToRx;
+
+ begin
+ $display( "ScriptSendPacket( 0x%04x, %0d )", Length, ExpectToRx );
+ SendPacket( Length, ExpectToRx );
+ if ( ExpectToRx != 0 )
+ RxExpectPacketCount = RxExpectPacketCount + 1;
+ end
+ endtask
+
+ `define SCRIPTLEN 10000
+ integer i;
+ reg [7:0] Script[0:`SCRIPTLEN-1];
+
+ function [15:0] Get16bit;
+ input Dummy;
+
+ reg [15:0] Data;
+
+ begin
+ Data[15:8] = Script[PC];
+ Data[7:0] = Script[PC+1];
+ PC = PC+2;
+
+ Get16bit = Data;
+ end
+ endfunction
+
+ task ExecuteScript;
+
+ reg [7:0] OpCode;
+ reg [15:0] Addr;
+ reg [15:0] Data;
+ reg [15:0] Length;
+ reg [15:0] Count;
+ reg [15:0] Mask;
+
+ reg ScriptDone;
+
+ begin
+ ScriptDone = 0;
+ Error = 0;
+ PC = 0;
+
+ while ( !ScriptDone )
+ begin
+ OpCode = Script[PC];
+ //$write( "PC=%0d, OpCode=%02x: ", PC, OpCode );
+ PC = PC+1;
+
+ casez ( OpCode )
+ 8'h00: // NOP
+ begin
+// $display( "NOP" );
+ #10;
+ end
+ 8'h01: // Write
+ begin
+ Addr = Get16bit(i);
+ Data = Get16bit(i);
+ ScriptWriteReg( Addr, Data );
+ end
+ 8'h02: // Read
+ begin
+ Addr = Get16bit(i);
+ ScriptReadReg( Addr );
+ end
+ 8'h03: // Read & match
+ begin
+ Addr = Get16bit(i);
+ Data = Get16bit(i);
+ Mask = Get16bit(i);
+ ScriptReadRegAndMatch( Addr, Data, Mask );
+ end
+
+ 8'h0f: // Delay
+ begin
+ Count = Get16bit(i);
+ $display( "Delay %0d", Count );
+ while ( Count > 0 )
+ begin
+ #10;
+ Count = Count - 1;
+ end
+ end
+
+ 8'h10: // Setup Tx Data
+ begin
+ Addr = Get16bit(i);
+ Length = Get16bit(i);
+ $write( "TxData( 0x%04x ), length=%0d: ", Addr, Length );
+ while ( Length != 0 )
+ begin
+ TxData[Addr] = Script[PC];
+ $write( " 0x%02x", Script[PC] );
+ PC = PC + 1;
+ Addr = Addr + 1;
+ Length = Length - 1;
+ end
+ $display( "" );
+ end
+
+ 8'h11: // Setup Alternative Tx Data
+ begin
+ Addr = Get16bit(i);
+ Length = Get16bit(i);
+ $write( "TxAltData( 0x%04x ), length=%0d: ", Addr, Length );
+ while ( Length != 0 )
+ begin
+ TxAltData[Addr] = Script[PC];
+ $write( " 0x%02x", Script[PC] );
+ PC = PC + 1;
+ Addr = Addr + 1;
+ Length = Length - 1;
+ end
+ $display( "" );
+ end
+
+ 8'h20: // Transmit packet - and put it on Rx expectancy queue
+ begin
+ Length = Get16bit(i); // Length in bytes
+ Count = Get16bit(i); // Number of times
+ while ( Count != 0 )
+ begin
+ ScriptSendPacket( Length, 1 );
+ Count = Count - 1;
+ end
+ end
+
+ 8'h21: // Transmit packet - but DON'T put it on Rx expectancy queue
+ begin
+ Length = Get16bit(i); // Length in bytes
+ Count = Get16bit(i); // Number of times
+ while ( Count != 0 )
+ begin
+ ScriptSendPacket( Length, 0 );
+ Count = Count - 1;
+ end
+ end
+
+ 8'h22: // Wait
+ begin : OpCode22
+ reg NoTimeOut;
+ Count = Get16bit(i); // Timeout in ns
+ if ( Count==0 )
+ NoTimeOut = 1;
+ else
+ NoTimeOut = 0;
+
+ $display( "Waiting for # of Rx packets = # of Tx packets..." );
+ $display( "Timeout = %0d ns - Current # Rx =%0d, Expected=%0d",
+ Count, RxPacketCount, RxExpectPacketCount );
+
+ while( (NoTimeOut || (Count != 0)) && ( RxExpectPacketCount != RxPacketCount ) && !Error )
+ begin
+ #1;
+ if ( !NoTimeOut )
+ Count = Count - 1;
+ //$display( "NoTimeOut=%0d, Count=%0d", NoTimeOut, Count );
+ end
+
+ if ( !Error )
+ if ( RxExpectPacketCount != RxPacketCount )
+ begin
+ $display( "ERROR: Timeout waiting for Rx packet(s)!" );
+ ScriptDone = 1;
+ Error = 1;
+ end
+ else
+ $display( "...Done waiting (time remaining = %0d ns)!", Count );
+ end
+
+ 8'h23: // Inject bit error in Tx packet
+ begin
+ InjectError = Get16bit(i); // Get bit error pattern
+ $display( "Injecting a single bit-error in Tx packet: TxEr=%0d, TxEn=%0d, TxD=0x%02h (0x%03h)",
+ InjectError[9], InjectError[8], InjectError[7:0], InjectError );
+ end
+
+ 8'h24: // Store internally generated PAUSE frame in Rx expect queue
+ begin
+ Count = Get16bit(i); // Timeout in ns
+ $display( "Generating PAUSE frame (tick=%0d) on Rx expect queue", Count );
+ RxExpectPacketCount = RxExpectPacketCount + 1;
+ FIFO_Wr( { 1'b1, 1'b0, 2'b00, 32'h0180c200 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 16'h0001, 16'h0000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h88080001 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, Count, 16'h0000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b0, 2'b00, 32'h00000000 } );
+ FIFO_Wr( { 1'b0, 1'b1, 2'b00, 32'h00000000 } );
+ end
+
+ 8'h25: // Transmit packet - and indicate that it must be IGNORED upon reception
+ begin
+ Length = Get16bit(i); // Length in bytes
+ Count = Get16bit(i); // Number of times
+ while ( Count != 0 )
+ begin
+ ScriptSendPacket( Length, 3 );
+ Count = Count - 1;
+ end
+ end
+
+ 8'h26: // Transmit packet - and put it on expectancy queue with Alternate header!
+ begin
+ Length = Get16bit(i); // Length in bytes
+ Count = Get16bit(i); // Number of times
+ while ( Count != 0 )
+ begin
+ ScriptSendPacket( Length, 2 );
+ Count = Count - 1;
+ end
+ end
+
+ 8'hff: // Halt
+ begin
+ $display( "HALT" );
+ ScriptDone = 1;
+ Done = 1;
+ end
+
+ default: // Unknown opcode
+ begin
+ $display( "Unknown instruction encountered @ PC=%0d: OpCode=0x%02x", PC-1, OpCode );
+ Error = 1;
+ end
+
+ endcase
+
+ if ( Error )
+ begin
+ ScriptDone = 1;
+ Done = 1;
+ end
+ end
+
+ if ( Error )
+ $display( "ERROR: Test failed!");
+ else
+ begin : ScriptSuccess
+ real TxTimeElapsed;
+ real RxTimeElapsed;
+ real ReferenceTime;
+
+ ReferenceTime = $realtime;
+ #1;
+ ReferenceTime = $realtime - ReferenceTime;
+
+ TxTimeElapsed = $realtime - TxStartTime;
+ RxTimeElapsed = $realtime - RxStartTime;
+
+ $display( "TxStartTime=%0e, Now=%0e", TxStartTime, $realtime );
+ $display( "RxStartTime=%0e, Now=%0e", RxStartTime, $realtime );
+
+ $display( "Tx stats: %0d packet(s) send, total of %0d bytes in %0e ns ~ %1.2f Mbps",
+ TxPacketCount, TxByteCount, TxTimeElapsed, TxByteCount*8*1e3/TxTimeElapsed );
+ $display( "Rx stats: %0d packet(s) received, total of %0d bytes in %0e ns ~ %1.2f Mbps",
+ RxPacketCount, RxByteCount, RxTimeElapsed, RxByteCount*8*1e3/RxTimeElapsed );
+ $display( "Test succeeded!");
+ end
+
+ end
+ endtask
+
+ //-------------------------------------------------------------------------
+ // Generate all clocks
+ //-------------------------------------------------------------------------
+
+ // GMII master clock (125 MHz)
+ initial
+ begin
+ #10;
+ while ( !Done )
+ begin
+ #4 Clk_125M = 0;
+ #4 Clk_125M = 1;
+ end
+ end
+
+ // User (packet) interface clock (100 MHz)
+ initial
+ begin
+ #10;
+ while ( !Done )
+ begin
+ #5 Clk_user = 0;
+ #5 Clk_user = 1;
+ end
+ end
+
+ // Wishbone host interface clock (50 MHz)
+ initial
+ begin
+ #10;
+ while ( !Done )
+ begin
+ #10 CLK_I = 0;
+ #10 CLK_I = 1;
+ end
+ end
+
+ //-------------------------------------------------------------------------
+
+ initial
+ begin
+ if ( $test$plusargs( "vcd" ) )
+ begin
+ $display( "Turning VCD data dump on" );
+ $dumpfile();
+ $dumpvars( 0 ); // Dump all signals in entire design
+ end
+ end
+
+ //-------------------------------------------------------------------------
+
+ reg [1023:0] ScriptFile;
+
+ initial
+ begin
+ HostInit;
+
+ TxStartTime = 0;
+ RxStartTime = 0;
+ TxByteCount = 0;
+ RxByteCount = 0;
+
+ for ( i=0; i<`TXDATALEN; i=i+1 )
+ TxData[i] = (i & 8'hff);
+
+ // Fill script memory with HALTs
+ for ( i=0; i<`SCRIPTLEN; i=i+1 )
+ Script[i] = 8'hff;
+
+ if ( !$value$plusargs( "script=%s", ScriptFile ) )
+ begin
+ $display( "Using default script file" );
+ ScriptFile = "test.scr";
+ end
+
+ $readmemh( ScriptFile, Script );
+
+// for ( i=0; i<40; i=i+1 )
+// $display( "Script[%0d]=0x%02x", i, Script[i] );
+
+ #10;
+
+ ExecuteScript;
+ end
+
+endmodule
diff --git a/usrp2/fpga/eth/bench/verilog/test.scr b/usrp2/fpga/eth/bench/verilog/test.scr new file mode 100644 index 000000000..2ad127d31 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/test.scr @@ -0,0 +1,23 @@ +// This tests just runs trough a couple of different packet lengths
+
+// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+// Transmit a 320-byte frame 1 time - and expect it to be received again!
+20 01 40 00 01
+
+// Transmit a 80-byte frame 1 time - and expect it to be received again!
+20 00 50 00 01
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Halt
+FF
diff --git a/usrp2/fpga/eth/bench/verilog/txmac.scr b/usrp2/fpga/eth/bench/verilog/txmac.scr new file mode 100644 index 000000000..caa7db594 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/txmac.scr @@ -0,0 +1,93 @@ +// Read from register 24 to confirm that Rx CRC check is enabled
+03 00 18 00 01 ff ff
+
+// Set speed to 1000 Mbps
+01 00 22 00 04
+
+// Write MAC address 12 35 56 78 9A BC to Rx Address buffer
+01 00 10 00 00
+01 00 0f 00 12
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 01
+01 00 0f 00 34
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 02
+01 00 0f 00 56
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 03
+01 00 0f 00 78
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 04
+01 00 0f 00 9A
+01 00 11 00 01
+01 00 11 00 00
+01 00 10 00 05
+01 00 0f 00 BC
+01 00 11 00 01
+01 00 11 00 00
+
+// Write 1 to register 14, MAC_rx_add_chk_en
+// This turns on the Rx Destination MAC address filter
+01 00 0e 00 01
+
+// Setup Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC CBA987654321 0800
+// (i.e. Destination MAC address is 123456789ABC matching the above)
+10 00 00 00 0E 12 34 56 78 9A BC CB A9 87 65 43 21 08 00
+
+// Setup Alternate Tx and Rx MAC addresses and type field to "IP"
+// Set Tx Data at offset 0, length 14 to 123456789ABC 112233445566 0800
+// (i.e. Destination MAC address is 123456789ABC matching the above)
+11 00 00 00 0E 12 34 56 78 9A BC 11 22 33 44 55 66 08 00
+
+// Transmit a 60-byte frame 3 times - and expect them to be received again!
+20 00 3C 00 03
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Write MAC address 11 22 33 44 55 66 to Tx MAC Source Address buffer
+01 00 09 00 00
+01 00 08 00 11
+01 00 0a 00 01
+01 00 0a 00 00
+01 00 09 00 01
+01 00 08 00 22
+01 00 0a 00 01
+01 00 0a 00 00
+01 00 09 00 02
+01 00 08 00 33
+01 00 0a 00 01
+01 00 0a 00 00
+01 00 09 00 03
+01 00 08 00 44
+01 00 0a 00 01
+01 00 0a 00 00
+01 00 09 00 04
+01 00 08 00 55
+01 00 0a 00 01
+01 00 0a 00 00
+01 00 09 00 05
+01 00 08 00 66
+01 00 0a 00 01
+01 00 0a 00 00
+
+// Transmit a 60 byte frame 3 times - and expect them to be received again!
+20 00 3C 00 03
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
+
+// Write 1 to register 7, MAC_tx_add_en
+// This turns on the Tx Source MAC address replacement mechanism
+01 00 07 00 01
+
+// Transmit a 60 byte frame 3 times - and expect them to be received again with Alternate header!
+26 00 3C 00 03
+
+// Wait (indefinitely) for missing Rx packets
+22 00 00
diff --git a/usrp2/fpga/eth/bench/verilog/xlnx_glbl.v b/usrp2/fpga/eth/bench/verilog/xlnx_glbl.v new file mode 100644 index 000000000..662a60e35 --- /dev/null +++ b/usrp2/fpga/eth/bench/verilog/xlnx_glbl.v @@ -0,0 +1,29 @@ +module xlnx_glbl
+(
+ GSR,
+ GTS
+);
+
+ //--------------------------------------------------------------------------
+ // Parameters
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // IO declarations
+ //--------------------------------------------------------------------------
+
+ output GSR;
+ output GTS;
+
+ //--------------------------------------------------------------------------
+ // Local declarations
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // Internal declarations
+ //--------------------------------------------------------------------------
+
+ assign GSR = 0;
+ assign GTS = 0;
+
+endmodule
diff --git a/usrp2/fpga/eth/demo/verilog/RAMB16_S1_S2.v b/usrp2/fpga/eth/demo/verilog/RAMB16_S1_S2.v new file mode 100644 index 000000000..758760b95 --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/RAMB16_S1_S2.v @@ -0,0 +1,1535 @@ +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S1_S2.v,v 1.10 2005/03/14 22:54:41 wloo Exp $ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995/2005 Xilinx, Inc. +// All Right Reserved. +/////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor : Xilinx +// \ \ \/ Version : 8.1i (I.13) +// \ \ Description : Xilinx Functional Simulation Library Component +// / / 16K-Bit Data and 2K-Bit Parity Dual Port Block RAM +// /___/ /\ Filename : RAMB16_S1_S2.v +// \ \ / \ Timestamp : Thu Mar 10 16:43:35 PST 2005 +// \___\/\___\ +// +// Revision: +// 03/23/04 - Initial version. +// End Revision + +`ifdef legacy_model + +`timescale 1 ps / 1 ps + +module RAMB16_S1_S2 (DOA, DOB, ADDRA, ADDRB, CLKA, CLKB, DIA, DIB, ENA, ENB, SSRA, SSRB, WEA, WEB); + + parameter INIT_A = 1'h0; + parameter INIT_B = 2'h0; + parameter SRVAL_A = 1'h0; + parameter SRVAL_B = 2'h0; + parameter WRITE_MODE_A = "WRITE_FIRST"; + parameter WRITE_MODE_B = "WRITE_FIRST"; + parameter SIM_COLLISION_CHECK = "ALL"; + localparam SETUP_ALL = 1000; + localparam SETUP_READ_FIRST = 3000; + + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + output [0:0] DOA; + reg [0:0] doa_out; + wire doa_out0; + + input [13:0] ADDRA; + input [0:0] DIA; + input ENA, CLKA, WEA, SSRA; + + output [1:0] DOB; + reg [1:0] dob_out; + wire dob_out0, dob_out1; + + input [12:0] ADDRB; + input [1:0] DIB; + input ENB, CLKB, WEB, SSRB; + + reg [18431:0] mem; + reg [8:0] count; + reg [1:0] wr_mode_a, wr_mode_b; + + reg [5:0] dmi, dbi; + reg [5:0] pmi, pbi; + + wire [13:0] addra_int; + reg [13:0] addra_reg; + wire [0:0] dia_int; + wire ena_int, clka_int, wea_int, ssra_int; + reg ena_reg, wea_reg, ssra_reg; + wire [12:0] addrb_int; + reg [12:0] addrb_reg; + wire [1:0] dib_int; + wire enb_int, clkb_int, web_int, ssrb_int; + reg display_flag; + reg enb_reg, web_reg, ssrb_reg; + + time time_clka, time_clkb; + time time_clka_clkb; + time time_clkb_clka; + + reg setup_all_a_b; + reg setup_all_b_a; + reg setup_zero; + reg setup_rf_a_b; + reg setup_rf_b_a; + reg [1:0] data_collision, data_collision_a_b, data_collision_b_a; + reg memory_collision, memory_collision_a_b, memory_collision_b_a; + reg address_collision, address_collision_a_b, address_collision_b_a; + reg change_clka; + reg change_clkb; + + wire [14:0] data_addra_int; + wire [14:0] data_addra_reg; + wire [14:0] data_addrb_int; + wire [14:0] data_addrb_reg; + wire [15:0] parity_addra_int; + wire [15:0] parity_addra_reg; + wire [15:0] parity_addrb_int; + wire [15:0] parity_addrb_reg; + + tri0 GSR = glbl.GSR; + + always @(GSR) + if (GSR) begin + assign doa_out = INIT_A[0:0]; + assign dob_out = INIT_B[1:0]; + end + else begin + deassign doa_out; + deassign dob_out; + end + + buf b_doa_out0 (doa_out0, doa_out[0]); + buf b_dob_out0 (dob_out0, dob_out[0]); + buf b_dob_out1 (dob_out1, dob_out[1]); + + buf b_doa0 (DOA[0], doa_out0); + buf b_dob0 (DOB[0], dob_out0); + buf b_dob1 (DOB[1], dob_out1); + + buf b_addra_0 (addra_int[0], ADDRA[0]); + buf b_addra_1 (addra_int[1], ADDRA[1]); + buf b_addra_2 (addra_int[2], ADDRA[2]); + buf b_addra_3 (addra_int[3], ADDRA[3]); + buf b_addra_4 (addra_int[4], ADDRA[4]); + buf b_addra_5 (addra_int[5], ADDRA[5]); + buf b_addra_6 (addra_int[6], ADDRA[6]); + buf b_addra_7 (addra_int[7], ADDRA[7]); + buf b_addra_8 (addra_int[8], ADDRA[8]); + buf b_addra_9 (addra_int[9], ADDRA[9]); + buf b_addra_10 (addra_int[10], ADDRA[10]); + buf b_addra_11 (addra_int[11], ADDRA[11]); + buf b_addra_12 (addra_int[12], ADDRA[12]); + buf b_addra_13 (addra_int[13], ADDRA[13]); + buf b_dia_0 (dia_int[0], DIA[0]); + buf b_ena (ena_int, ENA); + buf b_clka (clka_int, CLKA); + buf b_ssra (ssra_int, SSRA); + buf b_wea (wea_int, WEA); + buf b_addrb_0 (addrb_int[0], ADDRB[0]); + buf b_addrb_1 (addrb_int[1], ADDRB[1]); + buf b_addrb_2 (addrb_int[2], ADDRB[2]); + buf b_addrb_3 (addrb_int[3], ADDRB[3]); + buf b_addrb_4 (addrb_int[4], ADDRB[4]); + buf b_addrb_5 (addrb_int[5], ADDRB[5]); + buf b_addrb_6 (addrb_int[6], ADDRB[6]); + buf b_addrb_7 (addrb_int[7], ADDRB[7]); + buf b_addrb_8 (addrb_int[8], ADDRB[8]); + buf b_addrb_9 (addrb_int[9], ADDRB[9]); + buf b_addrb_10 (addrb_int[10], ADDRB[10]); + buf b_addrb_11 (addrb_int[11], ADDRB[11]); + buf b_addrb_12 (addrb_int[12], ADDRB[12]); + buf b_dib_0 (dib_int[0], DIB[0]); + buf b_dib_1 (dib_int[1], DIB[1]); + buf b_enb (enb_int, ENB); + buf b_clkb (clkb_int, CLKB); + buf b_ssrb (ssrb_int, SSRB); + buf b_web (web_int, WEB); + + initial begin + for (count = 0; count < 256; count = count + 1) begin + mem[count] <= INIT_00[count]; + mem[256 * 1 + count] <= INIT_01[count]; + mem[256 * 2 + count] <= INIT_02[count]; + mem[256 * 3 + count] <= INIT_03[count]; + mem[256 * 4 + count] <= INIT_04[count]; + mem[256 * 5 + count] <= INIT_05[count]; + mem[256 * 6 + count] <= INIT_06[count]; + mem[256 * 7 + count] <= INIT_07[count]; + mem[256 * 8 + count] <= INIT_08[count]; + mem[256 * 9 + count] <= INIT_09[count]; + mem[256 * 10 + count] <= INIT_0A[count]; + mem[256 * 11 + count] <= INIT_0B[count]; + mem[256 * 12 + count] <= INIT_0C[count]; + mem[256 * 13 + count] <= INIT_0D[count]; + mem[256 * 14 + count] <= INIT_0E[count]; + mem[256 * 15 + count] <= INIT_0F[count]; + mem[256 * 16 + count] <= INIT_10[count]; + mem[256 * 17 + count] <= INIT_11[count]; + mem[256 * 18 + count] <= INIT_12[count]; + mem[256 * 19 + count] <= INIT_13[count]; + mem[256 * 20 + count] <= INIT_14[count]; + mem[256 * 21 + count] <= INIT_15[count]; + mem[256 * 22 + count] <= INIT_16[count]; + mem[256 * 23 + count] <= INIT_17[count]; + mem[256 * 24 + count] <= INIT_18[count]; + mem[256 * 25 + count] <= INIT_19[count]; + mem[256 * 26 + count] <= INIT_1A[count]; + mem[256 * 27 + count] <= INIT_1B[count]; + mem[256 * 28 + count] <= INIT_1C[count]; + mem[256 * 29 + count] <= INIT_1D[count]; + mem[256 * 30 + count] <= INIT_1E[count]; + mem[256 * 31 + count] <= INIT_1F[count]; + mem[256 * 32 + count] <= INIT_20[count]; + mem[256 * 33 + count] <= INIT_21[count]; + mem[256 * 34 + count] <= INIT_22[count]; + mem[256 * 35 + count] <= INIT_23[count]; + mem[256 * 36 + count] <= INIT_24[count]; + mem[256 * 37 + count] <= INIT_25[count]; + mem[256 * 38 + count] <= INIT_26[count]; + mem[256 * 39 + count] <= INIT_27[count]; + mem[256 * 40 + count] <= INIT_28[count]; + mem[256 * 41 + count] <= INIT_29[count]; + mem[256 * 42 + count] <= INIT_2A[count]; + mem[256 * 43 + count] <= INIT_2B[count]; + mem[256 * 44 + count] <= INIT_2C[count]; + mem[256 * 45 + count] <= INIT_2D[count]; + mem[256 * 46 + count] <= INIT_2E[count]; + mem[256 * 47 + count] <= INIT_2F[count]; + mem[256 * 48 + count] <= INIT_30[count]; + mem[256 * 49 + count] <= INIT_31[count]; + mem[256 * 50 + count] <= INIT_32[count]; + mem[256 * 51 + count] <= INIT_33[count]; + mem[256 * 52 + count] <= INIT_34[count]; + mem[256 * 53 + count] <= INIT_35[count]; + mem[256 * 54 + count] <= INIT_36[count]; + mem[256 * 55 + count] <= INIT_37[count]; + mem[256 * 56 + count] <= INIT_38[count]; + mem[256 * 57 + count] <= INIT_39[count]; + mem[256 * 58 + count] <= INIT_3A[count]; + mem[256 * 59 + count] <= INIT_3B[count]; + mem[256 * 60 + count] <= INIT_3C[count]; + mem[256 * 61 + count] <= INIT_3D[count]; + mem[256 * 62 + count] <= INIT_3E[count]; + mem[256 * 63 + count] <= INIT_3F[count]; + end + address_collision <= 0; + address_collision_a_b <= 0; + address_collision_b_a <= 0; + change_clka <= 0; + change_clkb <= 0; + data_collision <= 0; + data_collision_a_b <= 0; + data_collision_b_a <= 0; + memory_collision <= 0; + memory_collision_a_b <= 0; + memory_collision_b_a <= 0; + setup_all_a_b <= 0; + setup_all_b_a <= 0; + setup_zero <= 0; + setup_rf_a_b <= 0; + setup_rf_b_a <= 0; + end + + assign data_addra_int = addra_int * 1; + assign data_addra_reg = addra_reg * 1; + assign data_addrb_int = addrb_int * 2; + assign data_addrb_reg = addrb_reg * 2; + + + initial begin + + display_flag = 1; + + case (SIM_COLLISION_CHECK) + + "NONE" : begin + assign setup_all_a_b = 1'b0; + assign setup_all_b_a = 1'b0; + assign setup_zero = 1'b0; + assign setup_rf_a_b = 1'b0; + assign setup_rf_b_a = 1'b0; + assign display_flag = 0; + end + "WARNING_ONLY" : begin + assign data_collision = 2'b00; + assign data_collision_a_b = 2'b00; + assign data_collision_b_a = 2'b00; + assign memory_collision = 1'b0; + assign memory_collision_a_b = 1'b0; + assign memory_collision_b_a = 1'b0; + end + "GENERATE_X_ONLY" : begin + assign display_flag = 0; + end + "ALL" : ; + default : begin + $display("Attribute Syntax Error : The Attribute SIM_COLLISION_CHECK on RAMB16_S1_S2 instance %m is set to %s. Legal values for this attribute are ALL, NONE, WARNING_ONLY or GENERATE_X_ONLY.", SIM_COLLISION_CHECK); + $finish; + end + + endcase // case(SIM_COLLISION_CHECK) + + end // initial begin + + + always @(posedge clka_int) begin + time_clka = $time; + #0 time_clkb_clka = time_clka - time_clkb; + change_clka = ~change_clka; + end + + always @(posedge clkb_int) begin + time_clkb = $time; + #0 time_clka_clkb = time_clkb - time_clka; + change_clkb = ~change_clkb; + end + + always @(change_clkb) begin + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_ALL)) + setup_all_a_b = 1; + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_READ_FIRST)) + setup_rf_a_b = 1; + end + + always @(change_clka) begin + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_ALL)) + setup_all_b_a = 1; + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_READ_FIRST)) + setup_rf_b_a = 1; + end + + always @(change_clkb or change_clka) begin + if ((time_clkb_clka == 0) && (time_clka_clkb == 0)) + setup_zero = 1; + end + + always @(posedge setup_zero) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_int[14:1] == data_addrb_int[14:1])) + memory_collision <= 1; + end + + always @(posedge setup_all_a_b or posedge setup_rf_a_b) begin + if ((ena_reg == 1) && (wea_reg == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_reg[14:1] == data_addrb_int[14:1])) + memory_collision_a_b <= 1; + end + + always @(posedge setup_all_b_a or posedge setup_rf_b_a) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_reg == 1) && (web_reg == 1) && + (data_addra_int[14:1] == data_addrb_reg[14:1])) + memory_collision_b_a <= 1; + end + + always @(posedge setup_all_a_b) begin + if (data_addra_reg[14:1] == data_addrb_int[14:1]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) + 6'b000011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b010011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b010111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b011011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b100011 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_a_b <= 0; + end + + + always @(posedge setup_all_b_a) begin + if (data_addra_int[14:1] == data_addrb_reg[14:1]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) + 6'b000011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b000111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b001011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b010111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b011011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b001001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b011001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b101001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_b_a <= 0; + end + + + always @(posedge setup_zero) begin + if (data_addra_int[14:1] == data_addrb_int[14:1]) begin + if ((ena_int == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_int}) + 6'b000011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision <= 2'b01; display_wa_rb; end + endcase + end + end + setup_zero <= 0; + end + + task display_ra_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S1_S2:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port A while a write was requested to the same address on Port B. The write will be successful however the read value on Port A is unknown until the next CLKA cycle.", $time/1000.0, addra_int); + end + endtask + + task display_wa_rb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S1_S2:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port B while a write was requested to the same address on Port A. The write will be successful however the read value on Port B is unknown until the next CLKB cycle.", $time/1000.0, addrb_int); + end + endtask + + task display_wa_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S1_S2:%m at simulation time %.3f ns\nA write was requested to the same address simultaneously at both Port A and Port B of the RAM. The contents written to the RAM at address location %h (hex) of Port A and address location %h (hex) of Port B are unknown.", $time/1000.0, addra_int, addrb_int); + end + endtask + + + always @(posedge setup_rf_a_b) begin + if (data_addra_reg[14:1] == data_addrb_int[14:1]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) +// 6'b000011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b001011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b010011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b100011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b100111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b101011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b001001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b011001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b101001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b010010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b010110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b011010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b100010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_a_b <= 0; + end + + + always @(posedge setup_rf_b_a) begin + if (data_addra_int[14:1] == data_addrb_reg[14:1]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) +// 6'b000011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b000111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b001011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b010011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b010111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b011011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b100011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end +// 6'b101011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b001001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b011001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b101001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_b_a <= 0; + end + + + always @(posedge clka_int) begin + addra_reg <= addra_int; + ena_reg <= ena_int; + ssra_reg <= ssra_int; + wea_reg <= wea_int; + end + + always @(posedge clkb_int) begin + addrb_reg <= addrb_int; + enb_reg <= enb_int; + ssrb_reg <= ssrb_int; + web_reg <= web_int; + end + + // Data + always @(posedge memory_collision) begin + for (dmi = 0; dmi < 1; dmi = dmi + 1) begin + mem[data_addra_int + dmi] <= 1'bX; + end + memory_collision <= 0; + end + + always @(posedge memory_collision_a_b) begin + for (dmi = 0; dmi < 1; dmi = dmi + 1) begin + mem[data_addra_reg + dmi] <= 1'bX; + end + memory_collision_a_b <= 0; + end + + always @(posedge memory_collision_b_a) begin + for (dmi = 0; dmi < 1; dmi = dmi + 1) begin + mem[data_addra_int + dmi] <= 1'bX; + end + memory_collision_b_a <= 0; + end + + always @(posedge data_collision[1]) begin + if (ssra_int == 0) begin + doa_out <= 1'bX; + end + data_collision[1] <= 0; + end + + always @(posedge data_collision[0]) begin + if (ssrb_int == 0) begin + for (dbi = 0; dbi < 1; dbi = dbi + 1) begin + dob_out[data_addra_int[0 : 0] + dbi] <= 1'bX; + end + end + data_collision[0] <= 0; + end + + always @(posedge data_collision_a_b[1]) begin + if (ssra_reg == 0) begin + doa_out <= 1'bX; + end + data_collision_a_b[1] <= 0; + end + + always @(posedge data_collision_a_b[0]) begin + if (ssrb_int == 0) begin + for (dbi = 0; dbi < 1; dbi = dbi + 1) begin + dob_out[data_addra_reg[0 : 0] + dbi] <= 1'bX; + end + end + data_collision_a_b[0] <= 0; + end + + always @(posedge data_collision_b_a[1]) begin + if (ssra_int == 0) begin + doa_out <= 1'bX; + end + data_collision_b_a[1] <= 0; + end + + always @(posedge data_collision_b_a[0]) begin + if (ssrb_reg == 0) begin + for (dbi = 0; dbi < 1; dbi = dbi + 1) begin + dob_out[data_addra_int[0 : 0] + dbi] <= 1'bX; + end + end + data_collision_b_a[0] <= 0; + end + + + initial begin + case (WRITE_MODE_A) + "WRITE_FIRST" : wr_mode_a <= 2'b00; + "READ_FIRST" : wr_mode_a <= 2'b01; + "NO_CHANGE" : wr_mode_a <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_A on RAMB16_S1_S2 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_A); + $finish; + end + endcase + end + + initial begin + case (WRITE_MODE_B) + "WRITE_FIRST" : wr_mode_b <= 2'b00; + "READ_FIRST" : wr_mode_b <= 2'b01; + "NO_CHANGE" : wr_mode_b <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_B on RAMB16_S1_S2 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_B); + $finish; + end + endcase + end + + // Port A + always @(posedge clka_int) begin + if (ena_int == 1'b1) begin + if (ssra_int == 1'b1) begin + doa_out[0] <= SRVAL_A[0]; + end + else begin + if (wea_int == 1'b1) begin + if (wr_mode_a == 2'b00) begin + doa_out <= dia_int; + end + else if (wr_mode_a == 2'b01) begin + doa_out[0] <= mem[data_addra_int + 0]; + end + end + else begin + doa_out[0] <= mem[data_addra_int + 0]; + end + end + end + end + + always @(posedge clka_int) begin + if (ena_int == 1'b1 && wea_int == 1'b1) begin + mem[data_addra_int + 0] <= dia_int[0]; + end + end + + // Port B + always @(posedge clkb_int) begin + if (enb_int == 1'b1) begin + if (ssrb_int == 1'b1) begin + dob_out[0] <= SRVAL_B[0]; + dob_out[1] <= SRVAL_B[1]; + end + else begin + if (web_int == 1'b1) begin + if (wr_mode_b == 2'b00) begin + dob_out <= dib_int; + end + else if (wr_mode_b == 2'b01) begin + dob_out[0] <= mem[data_addrb_int + 0]; + dob_out[1] <= mem[data_addrb_int + 1]; + end + end + else begin + dob_out[0] <= mem[data_addrb_int + 0]; + dob_out[1] <= mem[data_addrb_int + 1]; + end + end + end + end + + always @(posedge clkb_int) begin + if (enb_int == 1'b1 && web_int == 1'b1) begin + mem[data_addrb_int + 0] <= dib_int[0]; + mem[data_addrb_int + 1] <= dib_int[1]; + end + end + + specify + (CLKA *> DOA) = (100, 100); + (CLKB *> DOB) = (100, 100); + endspecify + +endmodule + +`else + +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S1_S2.v,v 1.10 2005/03/14 22:54:41 wloo Exp $ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995/2005 Xilinx, Inc. +// All Right Reserved. +/////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor : Xilinx +// \ \ \/ Version : 8.1i (I.13) +// \ \ Description : Xilinx Timing Simulation Library Component +// / / 16K-Bit Data and 2K-Bit Parity Dual Port Block RAM +// /___/ /\ Filename : RAMB16_S1_S2.v +// \ \ / \ Timestamp : Thu Mar 10 16:44:01 PST 2005 +// \___\/\___\ +// +// Revision: +// 03/23/04 - Initial version. +// 03/10/05 - Initialized outputs. +// End Revision + +`timescale 1 ps/1 ps + +module RAMB16_S1_S2 (DOA, DOB, ADDRA, ADDRB, CLKA, CLKB, DIA, DIB, ENA, ENB, SSRA, SSRB, WEA, WEB); + + parameter INIT_A = 1'h0; + parameter INIT_B = 2'h0; + parameter SRVAL_A = 1'h0; + parameter SRVAL_B = 2'h0; + parameter WRITE_MODE_A = "WRITE_FIRST"; + parameter WRITE_MODE_B = "WRITE_FIRST"; + parameter SIM_COLLISION_CHECK = "ALL"; + localparam SETUP_ALL = 1000; + localparam SETUP_READ_FIRST = 3000; + + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + output [0:0] DOA; + output [1:0] DOB; + + input [13:0] ADDRA; + input [0:0] DIA; + input ENA, CLKA, WEA, SSRA; + input [12:0] ADDRB; + input [1:0] DIB; + input ENB, CLKB, WEB, SSRB; + + reg [0:0] doa_out = INIT_A[0:0]; + reg [1:0] dob_out = INIT_B[1:0]; + + reg [1:0] mem [8191:0]; + + reg [8:0] count, countp; + reg [1:0] wr_mode_a, wr_mode_b; + + reg [5:0] dmi, dbi; + reg [5:0] pmi, pbi; + + wire [13:0] addra_int; + reg [13:0] addra_reg; + wire [0:0] dia_int; + wire ena_int, clka_int, wea_int, ssra_int; + reg ena_reg, wea_reg, ssra_reg; + wire [12:0] addrb_int; + reg [12:0] addrb_reg; + wire [1:0] dib_int; + wire enb_int, clkb_int, web_int, ssrb_int; + reg display_flag, output_flag; + reg enb_reg, web_reg, ssrb_reg; + + time time_clka, time_clkb; + time time_clka_clkb; + time time_clkb_clka; + + reg setup_all_a_b; + reg setup_all_b_a; + reg setup_zero; + reg setup_rf_a_b; + reg setup_rf_b_a; + reg [1:0] data_collision, data_collision_a_b, data_collision_b_a; + reg memory_collision, memory_collision_a_b, memory_collision_b_a; + reg change_clka; + reg change_clkb; + + wire [14:0] data_addra_int; + wire [14:0] data_addra_reg; + wire [14:0] data_addrb_int; + wire [14:0] data_addrb_reg; + + wire dia_enable = ena_int && wea_int; + wire dib_enable = enb_int && web_int; + + tri0 GSR = glbl.GSR; + wire gsr_int; + + buf b_gsr (gsr_int, GSR); + + buf b_doa [0:0] (DOA, doa_out); + buf b_addra [13:0] (addra_int, ADDRA); + buf b_dia [0:0] (dia_int, DIA); + buf b_ena (ena_int, ENA); + buf b_clka (clka_int, CLKA); + buf b_ssra (ssra_int, SSRA); + buf b_wea (wea_int, WEA); + + buf b_dob [1:0] (DOB, dob_out); + buf b_addrb [12:0] (addrb_int, ADDRB); + buf b_dib [1:0] (dib_int, DIB); + buf b_enb (enb_int, ENB); + buf b_clkb (clkb_int, CLKB); + buf b_ssrb (ssrb_int, SSRB); + buf b_web (web_int, WEB); + + + always @(gsr_int) + if (gsr_int) begin + assign {doa_out} = INIT_A; + assign {dob_out} = INIT_B; + end + else begin + deassign doa_out; + deassign dob_out; + end + + + initial begin + + for (count = 0; count < 128; count = count + 1) begin + mem[count] = INIT_00[(count * 2) +: 2]; + mem[128 * 1 + count] = INIT_01[(count * 2) +: 2]; + mem[128 * 2 + count] = INIT_02[(count * 2) +: 2]; + mem[128 * 3 + count] = INIT_03[(count * 2) +: 2]; + mem[128 * 4 + count] = INIT_04[(count * 2) +: 2]; + mem[128 * 5 + count] = INIT_05[(count * 2) +: 2]; + mem[128 * 6 + count] = INIT_06[(count * 2) +: 2]; + mem[128 * 7 + count] = INIT_07[(count * 2) +: 2]; + mem[128 * 8 + count] = INIT_08[(count * 2) +: 2]; + mem[128 * 9 + count] = INIT_09[(count * 2) +: 2]; + mem[128 * 10 + count] = INIT_0A[(count * 2) +: 2]; + mem[128 * 11 + count] = INIT_0B[(count * 2) +: 2]; + mem[128 * 12 + count] = INIT_0C[(count * 2) +: 2]; + mem[128 * 13 + count] = INIT_0D[(count * 2) +: 2]; + mem[128 * 14 + count] = INIT_0E[(count * 2) +: 2]; + mem[128 * 15 + count] = INIT_0F[(count * 2) +: 2]; + mem[128 * 16 + count] = INIT_10[(count * 2) +: 2]; + mem[128 * 17 + count] = INIT_11[(count * 2) +: 2]; + mem[128 * 18 + count] = INIT_12[(count * 2) +: 2]; + mem[128 * 19 + count] = INIT_13[(count * 2) +: 2]; + mem[128 * 20 + count] = INIT_14[(count * 2) +: 2]; + mem[128 * 21 + count] = INIT_15[(count * 2) +: 2]; + mem[128 * 22 + count] = INIT_16[(count * 2) +: 2]; + mem[128 * 23 + count] = INIT_17[(count * 2) +: 2]; + mem[128 * 24 + count] = INIT_18[(count * 2) +: 2]; + mem[128 * 25 + count] = INIT_19[(count * 2) +: 2]; + mem[128 * 26 + count] = INIT_1A[(count * 2) +: 2]; + mem[128 * 27 + count] = INIT_1B[(count * 2) +: 2]; + mem[128 * 28 + count] = INIT_1C[(count * 2) +: 2]; + mem[128 * 29 + count] = INIT_1D[(count * 2) +: 2]; + mem[128 * 30 + count] = INIT_1E[(count * 2) +: 2]; + mem[128 * 31 + count] = INIT_1F[(count * 2) +: 2]; + mem[128 * 32 + count] = INIT_20[(count * 2) +: 2]; + mem[128 * 33 + count] = INIT_21[(count * 2) +: 2]; + mem[128 * 34 + count] = INIT_22[(count * 2) +: 2]; + mem[128 * 35 + count] = INIT_23[(count * 2) +: 2]; + mem[128 * 36 + count] = INIT_24[(count * 2) +: 2]; + mem[128 * 37 + count] = INIT_25[(count * 2) +: 2]; + mem[128 * 38 + count] = INIT_26[(count * 2) +: 2]; + mem[128 * 39 + count] = INIT_27[(count * 2) +: 2]; + mem[128 * 40 + count] = INIT_28[(count * 2) +: 2]; + mem[128 * 41 + count] = INIT_29[(count * 2) +: 2]; + mem[128 * 42 + count] = INIT_2A[(count * 2) +: 2]; + mem[128 * 43 + count] = INIT_2B[(count * 2) +: 2]; + mem[128 * 44 + count] = INIT_2C[(count * 2) +: 2]; + mem[128 * 45 + count] = INIT_2D[(count * 2) +: 2]; + mem[128 * 46 + count] = INIT_2E[(count * 2) +: 2]; + mem[128 * 47 + count] = INIT_2F[(count * 2) +: 2]; + mem[128 * 48 + count] = INIT_30[(count * 2) +: 2]; + mem[128 * 49 + count] = INIT_31[(count * 2) +: 2]; + mem[128 * 50 + count] = INIT_32[(count * 2) +: 2]; + mem[128 * 51 + count] = INIT_33[(count * 2) +: 2]; + mem[128 * 52 + count] = INIT_34[(count * 2) +: 2]; + mem[128 * 53 + count] = INIT_35[(count * 2) +: 2]; + mem[128 * 54 + count] = INIT_36[(count * 2) +: 2]; + mem[128 * 55 + count] = INIT_37[(count * 2) +: 2]; + mem[128 * 56 + count] = INIT_38[(count * 2) +: 2]; + mem[128 * 57 + count] = INIT_39[(count * 2) +: 2]; + mem[128 * 58 + count] = INIT_3A[(count * 2) +: 2]; + mem[128 * 59 + count] = INIT_3B[(count * 2) +: 2]; + mem[128 * 60 + count] = INIT_3C[(count * 2) +: 2]; + mem[128 * 61 + count] = INIT_3D[(count * 2) +: 2]; + mem[128 * 62 + count] = INIT_3E[(count * 2) +: 2]; + mem[128 * 63 + count] = INIT_3F[(count * 2) +: 2]; + end + + + change_clka <= 0; + change_clkb <= 0; + data_collision <= 0; + data_collision_a_b <= 0; + data_collision_b_a <= 0; + memory_collision <= 0; + memory_collision_a_b <= 0; + memory_collision_b_a <= 0; + setup_all_a_b <= 0; + setup_all_b_a <= 0; + setup_zero <= 0; + setup_rf_a_b <= 0; + setup_rf_b_a <= 0; + end + + assign data_addra_int = addra_int * 1; + assign data_addra_reg = addra_reg * 1; + assign data_addrb_int = addrb_int * 2; + assign data_addrb_reg = addrb_reg * 2; + + + initial begin + + display_flag = 1; + output_flag = 1; + + case (SIM_COLLISION_CHECK) + + "NONE" : begin + output_flag = 0; + display_flag = 0; + end + "WARNING_ONLY" : output_flag = 0; + "GENERATE_ONLY" : display_flag = 0; + "ALL" : ; + + default : begin + $display("Attribute Syntax Error : The Attribute SIM_COLLISION_CHECK on RAMB16_S1_S2 instance %m is set to %s. Legal values for this attribute are ALL, NONE, WARNING_ONLY or GENERATE_ONLY.", SIM_COLLISION_CHECK); + $finish; + end + + endcase // case(SIM_COLLISION_CHECK) + + end // initial begin + + + always @(posedge clka_int) begin + if ((output_flag || display_flag)) begin + time_clka = $time; + #0 time_clkb_clka = time_clka - time_clkb; + change_clka = ~change_clka; + end + end + + always @(posedge clkb_int) begin + if ((output_flag || display_flag)) begin + time_clkb = $time; + #0 time_clka_clkb = time_clkb - time_clka; + change_clkb = ~change_clkb; + end + end + + always @(change_clkb) begin + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_ALL)) + setup_all_a_b = 1; + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_READ_FIRST)) + setup_rf_a_b = 1; + end + + always @(change_clka) begin + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_ALL)) + setup_all_b_a = 1; + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_READ_FIRST)) + setup_rf_b_a = 1; + end + + always @(change_clkb or change_clka) begin + if ((time_clkb_clka == 0) && (time_clka_clkb == 0)) + setup_zero = 1; + end + + always @(posedge setup_zero) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_int[14:1] == data_addrb_int[14:1])) + memory_collision <= 1; + end + + always @(posedge setup_all_a_b or posedge setup_rf_a_b) begin + if ((ena_reg == 1) && (wea_reg == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_reg[14:1] == data_addrb_int[14:1])) + memory_collision_a_b <= 1; + end + + always @(posedge setup_all_b_a or posedge setup_rf_b_a) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_reg == 1) && (web_reg == 1) && + (data_addra_int[14:1] == data_addrb_reg[14:1])) + memory_collision_b_a <= 1; + end + + always @(posedge setup_all_a_b) begin + if (data_addra_reg[14:1] == data_addrb_int[14:1]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) + 6'b000011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b010011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b010111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b011011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b100011 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_a_b <= 0; + end + + + always @(posedge setup_all_b_a) begin + if (data_addra_int[14:1] == data_addrb_reg[14:1]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) + 6'b000011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b000111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b001011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b010111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b011011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b001001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b011001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b101001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_b_a <= 0; + end + + + always @(posedge setup_zero) begin + if (data_addra_int[14:1] == data_addrb_int[14:1]) begin + if ((ena_int == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_int}) + 6'b000011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision <= 2'b01; display_wa_rb; end + endcase + end + end + setup_zero <= 0; + end + + task display_ra_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S1_S2:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port A while a write was requested to the same address on Port B. The write will be successful however the read value on Port A is unknown until the next CLKA cycle.", $time/1000.0, addra_int); + end + endtask + + task display_wa_rb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S1_S2:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port B while a write was requested to the same address on Port A. The write will be successful however the read value on Port B is unknown until the next CLKB cycle.", $time/1000.0, addrb_int); + end + endtask + + task display_wa_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S1_S2:%m at simulation time %.3f ns\nA write was requested to the same address simultaneously at both Port A and Port B of the RAM. The contents written to the RAM at address location %h (hex) of Port A and address location %h (hex) of Port B are unknown.", $time/1000.0, addra_int, addrb_int); + end + endtask + + + always @(posedge setup_rf_a_b) begin + if (data_addra_reg[14:1] == data_addrb_int[14:1]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) +// 6'b000011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b001011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b010011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b100011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b100111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b101011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b001001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b011001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b101001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b010010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b010110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b011010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b100010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_a_b <= 0; + end + + + always @(posedge setup_rf_b_a) begin + if (data_addra_int[14:1] == data_addrb_reg[14:1]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) +// 6'b000011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b000111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b001011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b010011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b010111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b011011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b100011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end +// 6'b101011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b001001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b011001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b101001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_b_a <= 0; + end + + + always @(posedge clka_int) begin + if ((output_flag || display_flag)) begin + addra_reg <= addra_int; + ena_reg <= ena_int; + ssra_reg <= ssra_int; + wea_reg <= wea_int; + end + end + + always @(posedge clkb_int) begin + if ((output_flag || display_flag)) begin + addrb_reg <= addrb_int; + enb_reg <= enb_int; + ssrb_reg <= ssrb_int; + web_reg <= web_int; + end + end + + + // Data + always @(posedge memory_collision) begin + if ((output_flag || display_flag)) begin + mem[addra_int[13:1]][addra_int[0:0] * 1 +: 1] <= 1'bx; + memory_collision <= 0; + end + + end + + always @(posedge memory_collision_a_b) begin + if ((output_flag || display_flag)) begin + mem[addra_reg[13:1]][addra_reg[0:0] * 1 +: 1] <= 1'bx; + memory_collision_a_b <= 0; + end + end + + always @(posedge memory_collision_b_a) begin + if ((output_flag || display_flag)) begin + mem[addra_int[13:1]][addra_int[0:0] * 1 +: 1] <= 1'bx; + memory_collision_b_a <= 0; + end + end + + always @(posedge data_collision[1]) begin + if (ssra_int == 0 && output_flag) begin + doa_out <= #100 1'bX; + end + data_collision[1] <= 0; + end + + always @(posedge data_collision[0]) begin + if (ssrb_int == 0 && output_flag) begin + dob_out[addra_int[0:0] * 1 +: 1] <= #100 1'bX; + end + data_collision[0] <= 0; + end + + always @(posedge data_collision_a_b[1]) begin + if (ssra_reg == 0 && output_flag) begin + doa_out <= #100 1'bX; + end + data_collision_a_b[1] <= 0; + end + + always @(posedge data_collision_a_b[0]) begin + if (ssrb_int == 0 && output_flag) begin + dob_out[addra_reg[0:0] * 1 +: 1] <= #100 1'bX; + end + data_collision_a_b[0] <= 0; + end + + always @(posedge data_collision_b_a[1]) begin + if (ssra_int == 0 && output_flag) begin + doa_out <= #100 1'bX; + end + data_collision_b_a[1] <= 0; + end + + always @(posedge data_collision_b_a[0]) begin + if (ssrb_reg == 0 && output_flag) begin + dob_out[addra_int[0:0] * 1 +: 1] <= #100 1'bX; + end + data_collision_b_a[0] <= 0; + end + + + initial begin + case (WRITE_MODE_A) + "WRITE_FIRST" : wr_mode_a <= 2'b00; + "READ_FIRST" : wr_mode_a <= 2'b01; + "NO_CHANGE" : wr_mode_a <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_A on RAMB16_S1_S2 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_A); + $finish; + end + endcase + end + + initial begin + case (WRITE_MODE_B) + "WRITE_FIRST" : wr_mode_b <= 2'b00; + "READ_FIRST" : wr_mode_b <= 2'b01; + "NO_CHANGE" : wr_mode_b <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_B on RAMB16_S1_S2 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_B); + $finish; + end + endcase + end + + + // Port A + always @(posedge clka_int) begin + + if (ena_int == 1'b1) begin + + if (ssra_int == 1'b1) begin + {doa_out} <= #100 SRVAL_A; + end + else begin + if (wea_int == 1'b1) begin + if (wr_mode_a == 2'b00) begin + doa_out <= #100 dia_int; + end + else if (wr_mode_a == 2'b01) begin + + doa_out <= #100 mem[addra_int[13:1]][addra_int[0:0] * 1 +: 1]; + + end + end + else begin + + doa_out <= #100 mem[addra_int[13:1]][addra_int[0:0] * 1 +: 1]; + + end + end + + // memory + if (wea_int == 1'b1) begin + mem[addra_int[13:1]][addra_int[0:0] * 1 +: 1] <= dia_int; + end + + end + end + + + // Port B + always @(posedge clkb_int) begin + + if (enb_int == 1'b1) begin + + if (ssrb_int == 1'b1) begin + {dob_out} <= #100 SRVAL_B; + end + else begin + if (web_int == 1'b1) begin + if (wr_mode_b == 2'b00) begin + dob_out <= #100 dib_int; + end + else if (wr_mode_b == 2'b01) begin + dob_out <= #100 mem[addrb_int]; + end + end + else begin + dob_out <= #100 mem[addrb_int]; + end + end + + // memory + if (web_int == 1'b1) begin + mem[addrb_int] <= dib_int; + end + + end + end + + +endmodule + +`endif diff --git a/usrp2/fpga/eth/demo/verilog/demo.ucf b/usrp2/fpga/eth/demo/verilog/demo.ucf new file mode 100644 index 000000000..f3562b46b --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/demo.ucf @@ -0,0 +1,52 @@ +NET "Reset_n" LOC = "C15"; // PushButton #4
+NET "Clk_100M" LOC = "B15";
+NET "Clk_125M" LOC = "A16"; // GMII only
+
+NET "RS232_TXD" LOC = "A9";
+NET "RS232_RXD" LOC = "F1";
+
+NET "USB_TXD" LOC = "D1";
+NET "USB_RXD" LOC = "A8";
+
+NET "PHY_RESET_n" LOC = "E25";
+
+NET "PHY_RXC" LOC = "B13";
+NET "PHY_RXD<0>" LOC = "D16";
+NET "PHY_RXD<1>" LOC = "C16";
+NET "PHY_RXD<2>" LOC = "D15";
+NET "PHY_RXD<3>" LOC = "D14";
+NET "PHY_RXD<4>" LOC = "E14";
+NET "PHY_RXD<5>" LOC = "F14";
+NET "PHY_RXD<6>" LOC = "F11";
+NET "PHY_RXD<7>" LOC = "F12";
+NET "PHY_RXDV" LOC = "F13";
+NET "PHY_RXER" LOC = "E13";
+
+NET "PHY_GTX_CLK" LOC = "C26"; // GMII only
+NET "PHY_TXC" LOC = "A10";
+NET "PHY_TXD<0>" LOC = "H26";
+NET "PHY_TXD<1>" LOC = "H24";
+NET "PHY_TXD<2>" LOC = "G26";
+NET "PHY_TXD<3>" LOC = "G24";
+NET "PHY_TXD<4>" LOC = "F26";
+NET "PHY_TXD<5>" LOC = "F24";
+NET "PHY_TXD<6>" LOC = "E26";
+NET "PHY_TXD<7>" LOC = "E24";
+NET "PHY_TXEN" LOC = "D26";
+NET "PHY_TXER" LOC = "D24";
+
+NET "PHY_COL" LOC = "B24";
+NET "PHY_CRS" LOC = "D25";
+
+NET "PHY_MDC" LOC = "G25";
+NET "PHY_MDIO" LOC = "H25";
+
+NET "LED<1>" LOC = "D13"; // LED #1-4
+NET "LED<2>" LOC = "D12";
+NET "LED<3>" LOC = "C11";
+NET "LED<4>" LOC = "D11";
+
+NET "Clk_100M" PERIOD = 10.000 ; # 100 MHz
+NET "Clk_125M" PERIOD = 8.000 ; # 125 MHz
+NET "PHY_RXC" PERIOD = 8.000 ; # 125 MHz
+NET "PHY_TXC" PERIOD = 8.000 ; # 125 MHz
diff --git a/usrp2/fpga/eth/demo/verilog/demo.v b/usrp2/fpga/eth/demo/verilog/demo.v new file mode 100644 index 000000000..649903c9a --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/demo.v @@ -0,0 +1,378 @@ +module demo(
+ Reset_n,
+ Clk_100M,
+ Clk_125M, // GMII only
+
+ RS232_TXD,
+ RS232_RXD,
+
+ USB_TXD,
+ USB_RXD,
+
+ //--- 10/100/1000BASE-T Ethernet PHY (MII/GMII)
+ PHY_RESET_n,
+
+ PHY_RXC,
+ PHY_RXD,
+ PHY_RXDV,
+ PHY_RXER,
+
+ PHY_GTX_CLK, // GMII only
+ PHY_TXC,
+ PHY_TXD,
+ PHY_TXEN,
+ PHY_TXER,
+
+ PHY_COL,
+ PHY_CRS,
+
+ PHY_MDC,
+ PHY_MDIO,
+
+ // Misc. I/Os
+ LED,
+ Button
+);
+
+ input Reset_n;
+ input Clk_100M;
+ input Clk_125M; // GMII
+
+ output RS232_TXD;
+ input RS232_RXD;
+
+ output USB_TXD;
+ input USB_RXD;
+
+ //--- 10/100/1000BASE-T Ethernet PHY (MII/GMII)
+ output PHY_RESET_n;
+
+ input PHY_RXC;
+ input [7:0] PHY_RXD;
+ input PHY_RXDV;
+ input PHY_RXER;
+
+ output PHY_GTX_CLK; // GMII only
+ input PHY_TXC;
+ output [7:0] PHY_TXD;
+ output PHY_TXEN;
+ output PHY_TXER;
+
+ input PHY_COL;
+ input PHY_CRS;
+
+ output PHY_MDC;
+ inout PHY_MDIO;
+
+ // Misc. I/Os
+ output [1:4] LED;
+
+ input [1:4] Button;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ // Rename to "standard" core clock name
+ wire Clk = Clk_100M;
+
+ reg [27:0] Counter;
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ Counter <= 0;
+ else
+ Counter <= Counter + 1;
+
+ assign LED[1:4] = Counter[27:24];
+
+ //-------------------------------------------------------------------------
+ // Instantiation of sub-modules
+ //-------------------------------------------------------------------------
+
+ //--- UART ----------------------------------------------------------------
+
+ wire UART_RXD;
+ wire UART_TXD;
+ wire UART_RxValid;
+ wire [7:0] UART_RxData;
+ wire UART_TxReady;
+ wire UART_TxValid;
+ wire [7:0] UART_TxData;
+
+ demo_uart demo_uart(
+ .Reset_n( Reset_n ),
+ .Clk ( Clk ),
+
+ // Interface to UART PHY
+ .RXD_i( UART_RXD ),
+ .TXD_o( UART_TXD ),
+
+ // Clk is divided by (Prescaler+1) to generate 16x the bitrate
+`ifdef EHDL_SIMULATION
+ .Prescaler_i( 16'd3 ), // Corresponds to VERY FAST - for simulation only!
+`else
+ .Prescaler_i( 16'd650 ), // Corresponds to 9600 baud (assuming 100 MHz clock)
+`endif
+
+ // Pulsed when RxData is valid
+ .RxValid_o( UART_RxValid ),
+ .RxData_o ( UART_RxData ),
+
+ // Asserted when ready for a new Tx byte
+ .TxReady_o( UART_TxReady ),
+
+ // Pulsed when TxData is valid
+ .TxValid_i( UART_TxValid ),
+ .TxData_i ( UART_TxData )
+ );
+
+ // Transmit & receive in parallel on either RS232 or USB/RS232 interface
+// assign UART_RXD = RS232_RXD & USB_RXD; // RS232 signals are high when inactive
+ assign UART_RXD = RS232_RXD;
+
+ assign RS232_TXD = UART_TXD;
+ assign USB_TXD = UART_TXD;
+
+ //--- UART-to-Wishbone Master ---------------------------------------------
+
+ wire WB_STB_ETH;
+ wire WB_STB_PDM;
+ wire WB_STB_PG;
+ wire WB_CYC;
+ wire [14:0] WB_ADR;
+ wire WB_WE;
+ wire [15:0] WB_DAT_Wr;
+ wire [15:0] WB_DAT_Rd;
+ wire WB_ACK;
+
+ demo_wishbone_master demo_wishbone_master(
+ .Reset_n( Reset_n ),
+ .Clk ( Clk ),
+
+ //--- UART interface
+
+ // Pulsed when RxData_i is valid
+ .RxValid_i( UART_RxValid ),
+ .RxData_i ( UART_RxData ),
+
+ // Asserted when ready for a new Tx byte
+ .TxReady_i( UART_TxReady ),
+
+ // Pulsed when TxData_o is valid
+ .TxValid_o( UART_TxValid ),
+ .TxData_o ( UART_TxData ),
+
+ //--- Wishbone interface
+ .STB_ETH_O( WB_STB_ETH ),
+ .STB_PDM_O( WB_STB_PDM ),
+ .STB_PG_O ( WB_STB_PG ),
+ .CYC_O ( WB_CYC ),
+ .ADR_O ( WB_ADR ),
+ .WE_O ( WB_WE ),
+ .DAT_O ( WB_DAT_Wr ),
+ .DAT_I ( WB_DAT_Rd ),
+ .ACK_I ( WB_ACK )
+ );
+
+ //--- Wishbone clients ----------------------------------------------------
+
+ //--- Packet Descriptor Memory --------------------------------------------
+
+ wire [15:0] WB_DAT_Rd_PDM;
+ wire WB_ACK_PDM;
+
+ wire PDM_Rd;
+ wire [13:0] PDM_Addr;
+ wire [31:0] PDM_RdData;
+
+ demo_packet_descriptor_memory demo_packet_descriptor_memory(
+ .Reset_n( Reset_n ),
+ .Clk ( Clk ),
+
+ //--- Wishbone interface
+ .STB_I( WB_STB_PDM ),
+ .CYC_I( WB_CYC ),
+ .ADR_I( WB_ADR ),
+ .WE_I ( WB_WE ),
+ .DAT_I( WB_DAT_Wr ),
+ .DAT_O( WB_DAT_Rd_PDM ),
+ .ACK_O( WB_ACK_PDM ),
+
+ //--- Packet Generator interface
+ // RdData_o is always valid exactly one clock after Addr_i changes
+ // and Rd_i is asserted
+ .Rd_i ( PDM_Rd ),
+ .Addr_i ( PDM_Addr ),
+ .RdData_o( PDM_RdData )
+ );
+
+ //--- Packet Generator ----------------------------------------------------
+
+ wire [15:0] WB_DAT_Rd_PG;
+ wire WB_ACK_PG;
+
+ wire Rx_mac_ra;
+ wire Rx_mac_rd;
+ wire [31:0] Rx_mac_data;
+ wire [1:0] Rx_mac_BE;
+ wire Rx_mac_pa;
+ wire Rx_mac_sop;
+ wire Rx_mac_err;
+ wire Rx_mac_eop;
+
+ wire Tx_mac_wa;
+ wire Tx_mac_wr;
+ wire [31:0] Tx_mac_data;
+ wire [1:0] Tx_mac_BE;
+ wire Tx_mac_sop;
+ wire Tx_mac_eop;
+
+ demo_packet_generator demo_packet_generator(
+ .Reset_n( Reset_n ),
+ .Clk ( Clk ),
+
+ //--- Wishbone interface
+ .STB_I( WB_STB_PG ),
+ .CYC_I( WB_CYC ),
+ .ADR_I( WB_ADR[1:0] ),
+ .WE_I ( WB_WE ),
+ .DAT_I( WB_DAT_Wr ),
+ .DAT_O( WB_DAT_Rd_PG ),
+ .ACK_O( WB_ACK_PG ),
+
+ //--- Packet Descriptor Memory interface
+ // RdData_i is always valid exactly one clock after Addr_o changes
+ // and Rd_o is asserted
+ .Rd_o ( PDM_Rd ),
+ .Addr_o ( PDM_Addr ),
+ .RdData_i( PDM_RdData ),
+
+ //--- User (packet) interface
+ .Rx_mac_ra ( Rx_mac_ra ),
+ .Rx_mac_rd ( Rx_mac_rd ),
+ .Rx_mac_data( Rx_mac_data ),
+ .Rx_mac_BE ( Rx_mac_BE ),
+ .Rx_mac_pa ( Rx_mac_pa ),
+ .Rx_mac_sop ( Rx_mac_sop ),
+ .Rx_mac_err ( Rx_mac_err ),
+ .Rx_mac_eop ( Rx_mac_eop ),
+
+ .Tx_mac_wa ( Tx_mac_wa ),
+ .Tx_mac_wr ( Tx_mac_wr ),
+ .Tx_mac_data( Tx_mac_data ),
+ .Tx_mac_BE ( Tx_mac_BE ),
+ .Tx_mac_sop ( Tx_mac_sop ),
+ .Tx_mac_eop ( Tx_mac_eop )
+ );
+
+ //--- Simple Wishbone client ----------------------------------------------
+
+ reg [15:0] Reg1;
+ reg [15:0] Reg2;
+
+ reg WB_ACK_Reg;
+ reg [15:0] WB_DAT_Reg;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ WB_ACK_Reg <= 0;
+ WB_DAT_Reg <= 'b0;
+
+ Reg1 <= 16'h1234;
+ Reg2 <= 16'hABCD;
+ end
+ else
+ begin
+ WB_ACK_Reg <= 0;
+ if ( WB_CYC & ~( WB_STB_ETH | WB_STB_PG | WB_STB_PDM ) )
+ begin
+ WB_ACK_Reg <= 1;
+ if ( WB_WE )
+ begin
+ if ( WB_ADR[0] )
+ Reg2 <= WB_DAT_Wr;
+ else
+ Reg1 <= WB_DAT_Wr;
+ end
+ else
+ begin
+ if ( WB_ADR[0] )
+ WB_DAT_Reg <= Reg2;
+ else
+ WB_DAT_Reg <= Reg1;
+ end
+ end
+ end
+
+ //--- DUT - Ethernet Core -------------------------------------------------
+
+ wire [15:0] WB_DAT_Rd_ETH;
+ wire WB_ACK_ETH;
+
+ wire [2:0] Speed;
+
+ MAC_top dut(
+ // System signals
+ .Clk_125M( Clk_125M ),
+ .Clk_user( Clk ),
+ .Speed ( Speed ),
+
+ // Wishbone compliant core host interface
+ .RST_I( ~Reset_n ),
+ .CLK_I( Clk ),
+ .STB_I( WB_STB_ETH ),
+ .CYC_I( WB_CYC ),
+ .ADR_I( WB_ADR[6:0] ),
+ .WE_I ( WB_WE ),
+ .DAT_I( WB_DAT_Wr ),
+ .DAT_O( WB_DAT_Rd_ETH ),
+ .ACK_O( WB_ACK_ETH ),
+
+ // User (packet) interface
+ .Rx_mac_ra ( Rx_mac_ra ),
+ .Rx_mac_rd ( Rx_mac_rd ),
+ .Rx_mac_data( Rx_mac_data ),
+ .Rx_mac_BE ( Rx_mac_BE ),
+ .Rx_mac_pa ( Rx_mac_pa ),
+ .Rx_mac_sop ( Rx_mac_sop ),
+ .Rx_mac_err ( Rx_mac_err ),
+ .Rx_mac_eop ( Rx_mac_eop ),
+
+ .Tx_mac_wa ( Tx_mac_wa ),
+ .Tx_mac_wr ( Tx_mac_wr ),
+ .Tx_mac_data( Tx_mac_data ),
+ .Tx_mac_BE ( Tx_mac_BE ),
+ .Tx_mac_sop ( Tx_mac_sop ),
+ .Tx_mac_eop ( Tx_mac_eop ),
+
+ // PHY interface (GMII/MII)
+ .Gtx_clk( PHY_GTX_CLK ), // Used only in GMII mode
+ .Rx_clk ( PHY_RXC ),
+ .Tx_clk ( PHY_TXC ), // Used only in MII mode
+ .Tx_er ( PHY_TXER ),
+ .Tx_en ( PHY_TXEN ),
+ .Txd ( PHY_TXD ),
+ .Rx_er ( PHY_RXER ),
+ .Rx_dv ( PHY_RXDV ),
+ .Rxd ( PHY_RXD ),
+ .Crs ( PHY_CRS ),
+ .Col ( PHY_COL ),
+
+ // MDIO interface (to PHY)
+ .Mdio( PHY_MDIO ),
+ .Mdc ( PHY_MDC )
+ );
+
+ //--- Combination of Wishbone read data and acknowledge -------------------
+
+ assign WB_DAT_Rd = ({16{WB_ACK_Reg}} & WB_DAT_Reg ) |
+ ({16{WB_ACK_PDM}} & WB_DAT_Rd_PDM) |
+ ({16{WB_ACK_PG }} & WB_DAT_Rd_PG ) |
+ ({16{WB_ACK_ETH}} & WB_DAT_Rd_ETH);
+
+ assign WB_ACK = WB_ACK_Reg | WB_ACK_PDM | WB_ACK_PG | WB_ACK_ETH;
+
+ assign PHY_RESET_n = Reset_n;
+
+endmodule
diff --git a/usrp2/fpga/eth/demo/verilog/demo_packet_descriptor_memory.v b/usrp2/fpga/eth/demo/verilog/demo_packet_descriptor_memory.v new file mode 100644 index 000000000..a5588a7d1 --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/demo_packet_descriptor_memory.v @@ -0,0 +1,384 @@ +module demo_packet_descriptor_memory(
+ Reset_n,
+ Clk,
+
+ //--- Wishbone interface
+ STB_I,
+ CYC_I,
+ ADR_I,
+ WE_I,
+ DAT_I,
+ DAT_O,
+ ACK_O,
+
+ //--- Packet Generator interface
+ // RdData_o is always valid exactly one clock after Addr_i changes
+ // and Rd_i is asserted
+ Rd_i,
+ Addr_i,
+ RdData_o
+);
+
+ input Reset_n;
+ input Clk;
+
+ //--- Wishbone interface
+ input STB_I;
+ input CYC_I;
+ input [14:0] ADR_I;
+ input WE_I;
+ input [15:0] DAT_I;
+ output [15:0] DAT_O;
+ output ACK_O;
+
+ //--- Packet Generator interface
+ // RdData_o is always valid exactly one clock after Addr_i changes
+ // and Rd_i is asserted
+ input Rd_i;
+ input [13:0] Addr_i;
+ output [31:0] RdData_o;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ reg ACK_O;
+
+ //-------------------------------------------------------------------------
+
+ wire [15:0] WrDataA = DAT_I;
+ wire [15:0] RdDataA;
+ wire [31:0] RdDataB;
+
+ assign DAT_O = RdDataA;
+ assign RdData_o = RdDataB;
+
+ wire WB_Access = STB_I & CYC_I;
+ wire WB_AccessClock1;
+ reg WB_AccessClock2;
+
+ assign WB_AccessClock1 = WB_Access & ~WB_AccessClock2;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ WB_AccessClock2 <= 0;
+ ACK_O <= 0;
+ end
+ else
+ begin
+ WB_AccessClock2 <= WB_Access;
+ ACK_O <= WB_AccessClock1;
+ end
+
+ //-------------------------------------------------------------------------
+ // Instantiation of sub-modules
+ //-------------------------------------------------------------------------
+
+ //--- Instantiation of Xilinx 16 Kbit Dual Port Memory --------------------
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit0 (
+ .DOA( RdDataA[0] ),
+ .DOB( { RdDataB[0], RdDataB[16+0] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[0] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit1 (
+ .DOA( RdDataA[1] ),
+ .DOB( { RdDataB[1], RdDataB[16+1] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[1] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit2 (
+ .DOA( RdDataA[2] ),
+ .DOB( { RdDataB[2], RdDataB[16+2] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[2] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit3 (
+ .DOA( RdDataA[3] ),
+ .DOB( { RdDataB[3], RdDataB[16+3] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[3] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit4 (
+ .DOA( RdDataA[4] ),
+ .DOB( { RdDataB[4], RdDataB[16+4] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[4] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit5 (
+ .DOA( RdDataA[5] ),
+ .DOB( { RdDataB[5], RdDataB[16+5] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[5] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit6 (
+ .DOA( RdDataA[6] ),
+ .DOB( { RdDataB[6], RdDataB[16+6] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[6] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit7 (
+ .DOA( RdDataA[7] ),
+ .DOB( { RdDataB[7], RdDataB[16+7] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[7] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit8 (
+ .DOA( RdDataA[8] ),
+ .DOB( { RdDataB[8], RdDataB[16+8] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[8] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit9 (
+ .DOA( RdDataA[9] ),
+ .DOB( { RdDataB[9], RdDataB[16+9] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[9] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit10 (
+ .DOA( RdDataA[10] ),
+ .DOB( { RdDataB[10], RdDataB[16+10] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[10] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit11 (
+ .DOA( RdDataA[11] ),
+ .DOB( { RdDataB[11], RdDataB[16+11] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[11] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit12 (
+ .DOA( RdDataA[12] ),
+ .DOB( { RdDataB[12], RdDataB[16+12] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[12] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit13 (
+ .DOA( RdDataA[13] ),
+ .DOB( { RdDataB[13], RdDataB[16+13] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[13] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit14 (
+ .DOA( RdDataA[14] ),
+ .DOB( { RdDataB[14], RdDataB[16+14] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[14] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+ RAMB16_S1_S2 RAMB16_S1_S2_bit15 (
+ .DOA( RdDataA[15] ),
+ .DOB( { RdDataB[15], RdDataB[16+15] } ),
+
+ .ADDRA( ADR_I[13:0] ),
+ .DIA ( WrDataA[15] ),
+ .ENA ( WB_AccessClock1 ),
+ .CLKA ( Clk ),
+ .WEA ( WE_I ),
+ .SSRA ( 1'b0 ),
+
+ .ADDRB( Addr_i[12:0] ),
+ .DIB ( 2'b00 ),
+ .ENB ( Rd_i ),
+ .CLKB ( Clk ),
+ .WEB ( 1'b0 ),
+ .SSRB ( 1'b0 )
+ );
+
+endmodule
diff --git a/usrp2/fpga/eth/demo/verilog/demo_packet_generator.v b/usrp2/fpga/eth/demo/verilog/demo_packet_generator.v new file mode 100644 index 000000000..22ad52b4c --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/demo_packet_generator.v @@ -0,0 +1,274 @@ +module demo_packet_generator(
+ Reset_n,
+ Clk,
+
+ //--- Wishbone interface
+ STB_I,
+ CYC_I,
+ ADR_I,
+ WE_I,
+ DAT_I,
+ DAT_O,
+ ACK_O,
+
+ //--- Packet Descriptor Memory interface
+ // RdData_i is always valid exactly one clock after Addr_o changes
+ // and Rd_o is asserted
+ Rd_o,
+ Addr_o,
+ RdData_i,
+
+ //--- User (packet) interface
+ Rx_mac_ra,
+ Rx_mac_rd,
+ Rx_mac_data,
+ Rx_mac_BE,
+ Rx_mac_pa,
+ Rx_mac_sop,
+ Rx_mac_err,
+ Rx_mac_eop,
+
+ Tx_mac_wa,
+ Tx_mac_wr,
+ Tx_mac_data,
+ Tx_mac_BE,
+ Tx_mac_sop,
+ Tx_mac_eop
+);
+
+ input Reset_n;
+ input Clk;
+
+ //--- Wishbone interface
+ input STB_I;
+ input CYC_I;
+ input [1:0] ADR_I;
+ input WE_I;
+ input [15:0] DAT_I;
+ output [15:0] DAT_O;
+ output ACK_O;
+
+ //--- Packet Generator interface
+ // RdData_o is always valid exactly one clock after Addr_o changes
+ // and Rd_o is asserted
+ output Rd_o;
+ output [13:0] Addr_o;
+ input [31:0] RdData_i;
+
+ //--- User (packet) interface
+ input Rx_mac_ra;
+ output Rx_mac_rd;
+ input [31:0] Rx_mac_data;
+ input [1:0] Rx_mac_BE;
+ input Rx_mac_pa;
+ input Rx_mac_sop;
+ input Rx_mac_err;
+ input Rx_mac_eop;
+
+ input Tx_mac_wa;
+ output Tx_mac_wr;
+ output [31:0] Tx_mac_data;
+ output [1:0] Tx_mac_BE;
+ output Tx_mac_sop;
+ output Tx_mac_eop;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ reg ACK_O;
+ reg [15:0] DAT_O;
+
+ reg Rd_o;
+ reg Tx_mac_wr;
+ reg [1:0] Tx_mac_BE;
+ reg Tx_mac_sop;
+ reg Tx_mac_eop;
+
+ //--- Wishbone interface --------------------------------------------------
+
+ reg [1:0] PG_CFG;
+ wire PG_Enable = PG_CFG[0];
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ ACK_O <= 0;
+ DAT_O <= 'b0;
+
+ PG_CFG <= 2'h0;
+ end
+ else
+ begin
+ ACK_O <= 0;
+ if ( CYC_I & STB_I )
+ begin
+ ACK_O <= ~ACK_O; // Generate single cycle pulse!
+ if ( WE_I )
+ begin
+ PG_CFG <= DAT_I;
+ end
+ else
+ begin
+ DAT_O[1:0] <= PG_CFG;
+ end
+ end
+ end
+
+ //--- Packet Generator FSM ------------------------------------------------
+
+ parameter PG_FSM_STATE_IDLE = 3'h0;
+ parameter PG_FSM_STATE_LD_DESC_1 = 3'h1;
+ parameter PG_FSM_STATE_LD_DESC_2 = 3'h2;
+ parameter PG_FSM_STATE_RD_HEADER = 3'h3;
+ parameter PG_FSM_STATE_PAYLOAD_SEQ_NUMBER = 3'h4;
+ parameter PG_FSM_STATE_PAYLOAD = 3'h5;
+ parameter PG_FSM_STATE_DONE = 3'h6;
+ reg [2:0] PG_FSM_State;
+
+ reg [9:0] DescHigh; // Selects currente descriptor
+ reg [3:0] DescLow; // Index into a single descriptor (16 entries)
+
+ reg PDM_CFG1_LAST;
+ reg [3:0] PDM_CFG1_REPEAT;
+ reg [3:0] PDM_CFG1_HDRLEN;
+ reg [15:0] PDM_CFG2_PAYLDLEN;
+
+ reg [31:0] Tx_mac_data_reg;
+ reg WriteHeader;
+ reg [15:0] PayloadRemaining;
+ reg [31:0] PacketSequenceNumber;
+ reg [31:0] Payload;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ PG_FSM_State <= PG_FSM_STATE_IDLE;
+
+ Rd_o <= 0;
+
+ DescHigh <= 10'b0;
+ DescLow <= 4'b0;
+
+ Tx_mac_wr <= 0;
+ Tx_mac_sop <= 0;
+ Tx_mac_eop <= 0;
+ Tx_mac_BE <= 2'b00;
+
+ Tx_mac_data_reg <= 32'b0;
+ WriteHeader <= 0;
+ PayloadRemaining <= 16'd0;
+
+ PacketSequenceNumber <= 32'd0;
+ Payload <= 32'h0;
+
+ { PDM_CFG1_HDRLEN, PDM_CFG1_REPEAT, PDM_CFG1_LAST, PDM_CFG2_PAYLDLEN } <= 'b0;
+ end
+ else
+ begin
+ casez ( PG_FSM_State )
+ PG_FSM_STATE_IDLE:
+ if ( PG_Enable )
+ begin
+ PG_FSM_State <= PG_FSM_STATE_LD_DESC_1;
+ Rd_o <= 1;
+ end
+ else
+ begin
+ DescHigh <= 10'b0;
+ DescLow <= 4'b0;
+ end
+
+ PG_FSM_STATE_LD_DESC_1:
+ begin
+ PG_FSM_State <= PG_FSM_STATE_LD_DESC_2;
+
+ DescLow <= DescLow + 1;
+ end
+
+ PG_FSM_STATE_LD_DESC_2:
+ begin
+ PG_FSM_State <= PG_FSM_STATE_RD_HEADER;
+
+ { PDM_CFG1_LAST, PDM_CFG1_REPEAT, PDM_CFG1_HDRLEN, PDM_CFG2_PAYLDLEN } <=
+ { RdData_i[31], RdData_i[23:20], RdData_i[19:16], RdData_i[15:0] };
+ end
+
+ PG_FSM_STATE_RD_HEADER:
+ begin
+ Tx_mac_wr <= 0;
+ if ( Tx_mac_wa )
+ begin
+ // Space in Tx FIFO - write next header word
+ DescLow <= DescLow + 1;
+ Tx_mac_wr <= 1;
+ Tx_mac_sop <= ( DescLow == 1 ); // Assert SOP on first header word
+ WriteHeader <= 1;
+ if ( DescLow == PDM_CFG1_HDRLEN )
+ begin
+ // The requested number of header words has been read
+ // - proceed to generate packet payload
+ PG_FSM_State <= PG_FSM_STATE_PAYLOAD_SEQ_NUMBER;
+ PayloadRemaining <= PDM_CFG2_PAYLDLEN;
+ end
+ end
+ end
+
+ PG_FSM_STATE_PAYLOAD_SEQ_NUMBER:
+ begin
+ WriteHeader <= 0;
+ Tx_mac_data_reg <= PacketSequenceNumber;
+ Tx_mac_wr <= 0;
+ Tx_mac_sop <= 0;
+ if ( Tx_mac_wa )
+ begin
+ Tx_mac_wr <= 1;
+ PG_FSM_State <= PG_FSM_STATE_PAYLOAD;
+ Payload <= 32'h01020304;
+ PayloadRemaining <= PayloadRemaining - 4;
+ end
+ end
+
+ PG_FSM_STATE_PAYLOAD:
+ begin
+ Tx_mac_data_reg <= Payload;
+ Tx_mac_wr <= 0;
+ if ( Tx_mac_wa )
+ begin
+ Tx_mac_wr <= 1;
+ Tx_mac_data_reg <= Payload;
+ Payload[31:24] <= Payload[31:24] + 8'h04;
+ Payload[23:16] <= Payload[23:16] + 8'h04;
+ Payload[15: 8] <= Payload[15: 8] + 8'h04;
+ Payload[ 7: 0] <= Payload[ 7: 0] + 8'h04;
+ PayloadRemaining <= PayloadRemaining - 4;
+ if ( PayloadRemaining <= 4 )
+ begin
+ PG_FSM_State <= PG_FSM_STATE_DONE;
+
+ Tx_mac_eop <= 1;
+ // Indicate how many bytes are valid in this last transfer
+ Tx_mac_BE <= PayloadRemaining[1:0];
+ end
+ end
+ end
+
+ PG_FSM_STATE_DONE:
+ begin
+ // TBD: Add support for REPEAT, NEXT & LAST!
+ Tx_mac_wr <= 0;
+ Tx_mac_eop <= 0;
+ end
+ endcase
+ end
+
+ //-------------------------------------------------------------------------
+
+ assign Tx_mac_data = WriteHeader ?
+ RdData_i : Tx_mac_data_reg;
+
+ assign Addr_o = { DescHigh, DescLow };
+
+ assign Rx_mac_rd = 0;
+
+endmodule
diff --git a/usrp2/fpga/eth/demo/verilog/demo_uart.v b/usrp2/fpga/eth/demo/verilog/demo_uart.v new file mode 100644 index 000000000..ba4a3c35c --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/demo_uart.v @@ -0,0 +1,235 @@ +module demo_uart(
+ Reset_n,
+ Clk,
+
+ // Interface to UART PHY (RS232 level converter)
+ RXD_i,
+ TXD_o,
+
+ // Clk is divided by (Prescaler+1) to generate 16x the bitrate
+ Prescaler_i,
+
+ // Pulsed when RxData is valid
+ RxValid_o,
+ RxData_o,
+
+ // Asserted when ready for a new Tx byte
+ TxReady_o,
+
+ // Pulsed when TxData is valid
+ TxValid_i,
+ TxData_i
+);
+
+ input Reset_n;
+ input Clk;
+
+ // Interface to UART PHY (RS232 level converter)
+ input RXD_i;
+ output TXD_o;
+
+ // Clk is divided by (Prescaler+1) to generate 16x the bitrate
+ input [15:0] Prescaler_i;
+
+ // Pulsed when RxData is valid
+ output RxValid_o;
+ output [7:0] RxData_o;
+
+ // Asserted when ready for a new Tx byte
+ output TxReady_o;
+
+ // Pulsed when TxData is valid
+ input TxValid_i;
+ input [7:0] TxData_i;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ reg TXD_o;
+ reg RxValid_o;
+ reg [7:0] RxData_o;
+ reg TxReady_o;
+
+ //-------------------------------------------------------------------------
+ // Instantiation of sub-modules
+ //-------------------------------------------------------------------------
+
+ //--- Prescaler generating 16x bitrate clock ------------------------------
+
+ reg Clk_16x;
+ reg [15:0] Prescaler;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ Prescaler <= 0;
+ Clk_16x <= 0;
+ end
+ else
+ begin
+ if ( Prescaler == Prescaler_i )
+ begin
+ Prescaler <= 0;
+ Clk_16x <= 1;
+ end
+ else
+ begin
+ Prescaler <= Prescaler + 1;
+ Clk_16x <= 0;
+ end
+ end
+
+ //--- Transmitter logic ---------------------------------------------------
+
+ reg [3:0] TxCounter;
+ reg TxSendBit;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ TxCounter <= 0;
+ TxSendBit <= 0;
+ end
+ else
+ begin
+ TxSendBit <= 0;
+ if ( Clk_16x )
+ begin
+ if ( TxCounter == 15 )
+ begin
+ TxCounter <= 0;
+ TxSendBit <= 1;
+ end
+ else
+ TxCounter <= TxCounter + 1;
+ end
+ end
+
+ reg [7:0] TxData_reg;
+ reg [3:0] TxBitCnt;
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ TXD_o <= 1;
+ TxReady_o <= 1;
+ TxData_reg <= 0;
+ TxBitCnt <= 0;
+ end
+ else
+ begin
+ if ( TxReady_o )
+ begin
+ if ( TxValid_i )
+ begin
+ TxReady_o <= 0;
+ TxData_reg <= TxData_i;
+ TxBitCnt <= 0;
+ end
+ end
+ else
+ begin
+ if ( TxSendBit )
+ begin
+ // Only do anything on bit boundaries
+ casez ( TxBitCnt )
+ 0: // Tx START bit
+ TXD_o <= 0;
+ 10: // Tx second STOP bit
+ // Now we're done
+ TxReady_o <= 1;
+ default: // Tx data bit + first stop bit
+ begin
+ TXD_o <= TxData_reg[0];
+ TxData_reg <= { 1'b1, TxData_reg[7:1] };
+ end
+ endcase
+
+ TxBitCnt <= TxBitCnt+1;
+ end
+ end
+ end
+
+ //--- Receiver logic ------------------------------------------------------
+
+ reg RxHunt;
+ reg [3:0] RxCounter;
+ reg RxSampleBit;
+ reg RxDone;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ RxCounter <= 0;
+ RxSampleBit <= 0;
+
+ RxHunt <= 1;
+ end
+ else
+ begin
+ RxSampleBit <= 0;
+
+ if ( RxDone )
+ RxHunt <= 1;
+
+ if ( Clk_16x )
+ begin
+ if ( RxHunt )
+ begin
+ if ( RXD_i == 0 )
+ begin
+ // Receiving start bit!
+ RxHunt <= 0;
+ // Reset 16x bit counter
+ RxCounter <= 0;
+ end
+ end
+ else
+ begin
+ RxCounter <= RxCounter + 1;
+ if ( RxCounter == 7 )
+ // In middle of Rx bit in next cycle
+ RxSampleBit <= 1;
+ end
+ end
+ end
+
+ reg [3:0] RxBitCount;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ RxValid_o <= 0;
+ RxData_o <= 'b0;
+ RxBitCount <= 0;
+ RxDone <= 0;
+ end
+ else
+ begin
+ RxValid_o <= 0;
+ RxDone <= 0;
+
+ if ( RxSampleBit )
+ begin
+ RxBitCount <= RxBitCount + 1;
+
+ casez ( RxBitCount )
+ 0: // START bit - just ignore it
+ ;
+ 9: // STOP bit - indicate we're ready again
+ begin
+ RxDone <= 1;
+ RxBitCount <= 0;
+ end
+ default: // Rx Data bits
+ begin
+ RxData_o <= { RXD_i, RxData_o[7:1] };
+ if ( RxBitCount == 8 )
+ // Last data bit just received
+ RxValid_o <= 1;
+ end
+ endcase
+ end
+ end
+
+endmodule
diff --git a/usrp2/fpga/eth/demo/verilog/demo_wishbone_master.v b/usrp2/fpga/eth/demo/verilog/demo_wishbone_master.v new file mode 100644 index 000000000..b3c64fbcf --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/demo_wishbone_master.v @@ -0,0 +1,376 @@ +module demo_wishbone_master(
+ Reset_n,
+ Clk,
+
+ //--- UART interface
+
+ // Pulsed when RxData_i is valid
+ RxValid_i,
+ RxData_i,
+
+ // Asserted when ready for a new Tx byte
+ TxReady_i,
+
+ // Pulsed when TxData_o is valid
+ TxValid_o,
+ TxData_o,
+
+ //--- Wishbone interface
+ STB_ETH_O,
+ STB_PDM_O,
+ STB_PG_O,
+ CYC_O,
+ ADR_O,
+ WE_O,
+ DAT_O,
+ DAT_I,
+ ACK_I
+);
+
+ input Reset_n;
+ input Clk;
+
+ //--- UART interface
+
+ // Pulsed when RxData_i is valid
+ input RxValid_i;
+ input [7:0] RxData_i;
+
+ // Asserted when ready for a new Tx byte
+ input TxReady_i;
+
+ // Pulsed when TxData_o is valid
+ output TxValid_o;
+ output [7:0] TxData_o;
+
+ output STB_ETH_O;
+ output STB_PDM_O;
+ output STB_PG_O;
+ output CYC_O;
+ output [14:0] ADR_O;
+ output WE_O;
+ output [15:0] DAT_O;
+ input [15:0] DAT_I;
+ input ACK_I;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ reg TxValid_o;
+ reg [7:0] TxData_o;
+ reg STB_ETH_O;
+ reg STB_PDM_O;
+ reg STB_PG_O;
+ reg CYC_O;
+ reg [14:0] ADR_O;
+ reg WE_O;
+ reg [15:0] DAT_O;
+
+ //-------------------------------------------------------------------------
+ // Instantiation of sub-modules
+ //-------------------------------------------------------------------------
+
+ //--- Transmit FSM --------------------------------------------------------
+
+ parameter TX_STATE_IDLE = 0;
+ parameter TX_STATE_INIT = 1;
+ parameter TX_STATE_OK = 2;
+ parameter TX_STATE_ERROR = 3;
+ parameter TX_STATE_VALUE = 4;
+ parameter TX_STATE_LF = 5;
+
+ reg [2:0] TxState;
+ reg [3:0] TxIndex;
+ reg TxLast;
+
+ wire [15:0] TxValue16;
+ wire [3:0] TxHexDigit;
+ wire [7:0] TxHexChar;
+ reg TxOK;
+ reg TxERROR;
+ reg TxValue;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ TxState <= TX_STATE_INIT;
+ TxIndex <= 0;
+ TxLast <= 0;
+
+ TxValid_o <= 0;
+ TxData_o <= 'b0;
+ end
+ else
+ begin
+ TxValid_o <= 0;
+
+ // Don't do anything in cycle following TxValid_o being pulsed
+ if ( ~TxValid_o )
+ begin
+ casez ( TxState )
+ TX_STATE_INIT:
+ casez ( TxIndex )
+ 0: TxData_o <= "R";
+ 1: TxData_o <= "E";
+ 2: TxData_o <= "A";
+ 3: TxData_o <= "D";
+ 4: TxData_o <= "Y";
+ default: TxLast <= 1;
+ endcase
+
+ TX_STATE_OK:
+ casez ( TxIndex )
+ 0: TxData_o <= "O";
+ 1: TxData_o <= "K";
+ default: TxLast <= 1;
+ endcase
+
+ TX_STATE_ERROR:
+ casez ( TxIndex )
+ 0: TxData_o <= "E";
+ 1: TxData_o <= "R";
+ 2: TxData_o <= "R";
+ 3: TxData_o <= "O";
+ 4: TxData_o <= "R";
+ default: TxLast <= 1;
+ endcase
+
+ TX_STATE_VALUE:
+ casez ( TxIndex )
+ 0,1,2,3: TxData_o <= TxHexChar;
+ default: TxLast <= 1;
+ endcase
+
+ TX_STATE_LF:
+ ;
+
+ default:
+ begin
+ if ( TxOK )
+ TxState <= TX_STATE_OK;
+ else if ( TxERROR )
+ TxState <= TX_STATE_ERROR;
+ else if ( TxValue )
+ begin
+ TxState <= TX_STATE_VALUE;
+ TxIndex <= 0;
+ end
+ end
+ endcase
+
+ if ( (TxState != TX_STATE_IDLE) & TxReady_i )
+ begin
+ TxValid_o <= 1;
+
+ if ( TxLast )
+ begin
+ if ( TxState == TX_STATE_LF )
+ begin
+ TxData_o <= 10; // LF
+ TxState <= TX_STATE_IDLE;
+ TxIndex <= 0;
+ TxLast <= 0;
+ end
+ else
+ begin
+ TxData_o <= 13; // CR
+ TxState <= TX_STATE_LF;
+ end
+ end
+ else
+ TxIndex <= TxIndex + 1;
+ end
+ end
+ end
+
+ assign TxHexDigit = (TxIndex==0) ? TxValue16[15:12] :
+ (TxIndex==1) ? TxValue16[11: 8] :
+ (TxIndex==2) ? TxValue16[ 7: 4] :
+ TxValue16[ 3: 0];
+
+ assign TxHexChar = (TxHexDigit <= 9) ? (TxHexDigit + "0") :
+ (TxHexDigit + "A"-'hA);
+
+ //--- Receive FSM ---------------------------------------------------------
+
+ parameter RX_STATE_IDLE = 0;
+ parameter RX_STATE_VALUE16_FIRST = 1;
+ parameter RX_STATE_VALUE16 = 2;
+ parameter RX_STATE_COMMENT = 3;
+ parameter RX_STATE_CMD = 4;
+
+ reg [2:0] RxState;
+
+ wire IsWhiteSpace = ( RxData_i==" " ) |
+ ( RxData_i=="\t" ) |
+ ( RxData_i=="," ) |
+ ( RxData_i==10 ) |
+ ( RxData_i==13 );
+ wire IsHexDigit = (( RxData_i >= "0" ) & ( RxData_i <= "9" )) |
+ (( RxData_i >= "a" ) & ( RxData_i <= "f" )) |
+ (( RxData_i >= "A" ) & ( RxData_i <= "F" ));
+ wire [3:0] RxHexValue =
+ (( RxData_i >= "0" ) & ( RxData_i <= "9" )) ? RxData_i[3:0] :
+ (( RxData_i >= "a" ) & ( RxData_i <= "f" )) ? (RxData_i-"a"+'hA) :
+ (( RxData_i >= "A" ) & ( RxData_i <= "F" )) ? (RxData_i-"A"+'hA) : 0;
+
+ reg [15:0] RxValue16;
+ reg RxWrite;
+ reg RxWrData;
+
+ reg [15:0] RegAddr;
+ reg [15:0] RegRdData;
+
+ assign TxValue16 = RegRdData;
+
+ always @( negedge Reset_n or posedge Clk )
+ if ( ~Reset_n )
+ begin
+ RxState <= RX_STATE_IDLE;
+
+ RxValue16 <= 16'h0;
+ RxWrite <= 0;
+ RxWrData <= 0;
+
+ RegAddr <= 'b0;
+ RegRdData <= 'b0;
+
+ STB_ETH_O <= 0;
+ STB_PDM_O <= 0;
+ STB_PG_O <= 0;
+ CYC_O <= 0;
+ ADR_O <= 0;
+ WE_O <= 0;
+ DAT_O <= 0;
+
+ TxOK <= 0;
+ TxERROR <= 0;
+ TxValue <= 0;
+ end
+ else
+ begin
+ TxOK <= 0;
+ TxERROR <= 0;
+ TxValue <= 0;
+
+ if ( RxState == RX_STATE_CMD )
+ begin
+ STB_ETH_O <= ( RegAddr[15:12] == 4'h0 );
+ STB_PG_O <= ( RegAddr[15:12] == 4'h1 );
+ STB_PDM_O <= ( RegAddr[15] == 1'b1 );
+
+ CYC_O <= 1;
+ ADR_O <= RegAddr[14:0];
+ WE_O <= RxWrite;
+
+ if ( ACK_I )
+ begin
+ // Register transaction is completing!
+ CYC_O <= 0;
+ STB_ETH_O <= 0;
+ STB_PDM_O <= 0;
+ STB_PG_O <= 0;
+
+ // Latch data read in case of a read
+ RegRdData <= DAT_I;
+
+ if ( RxWrite )
+ // Transaction was a register write
+ TxOK <= 1;
+ else
+ TxValue <= 1;
+
+ RxState <= RX_STATE_IDLE;
+ end
+ end
+ else if ( (TxState == TX_STATE_IDLE) & RxValid_i )
+ begin
+ // A byte has been received!
+
+ casez ( RxState )
+ RX_STATE_IDLE:
+ if ( (RxData_i == "w") | (RxData_i == "W") )
+ begin
+ // Write Register Command: W rrrr dddd
+ RxState <= RX_STATE_VALUE16_FIRST;
+ RxWrite <= 1;
+ RxWrData <= 0;
+ end
+ else if ( (RxData_i == "r") | (RxData_i == "R") )
+ begin
+ // Read Register Command: R rrrr
+ RxState <= RX_STATE_VALUE16_FIRST;
+ RxWrite <= 0;
+ end
+ else if ( RxData_i == "/" )
+ begin
+ // Comment!
+ RxState <= RX_STATE_COMMENT;
+ end
+ else if ( ~IsWhiteSpace )
+ // Unknown command!
+ TxERROR <= 1;
+
+ RX_STATE_COMMENT:
+ if ( (RxData_i == 13) | (RxData_i == 10) )
+ // CR or LF - end of comment
+ RxState <= RX_STATE_IDLE;
+
+ RX_STATE_VALUE16_FIRST:
+ if ( IsHexDigit )
+ begin
+ RxValue16 <= { 12'b0, RxHexValue };
+ RxState <= RX_STATE_VALUE16;
+ end
+ else if ( ~IsWhiteSpace )
+ begin
+ // Unexpected character!
+ TxERROR <= 1;
+ RxState <= RX_STATE_IDLE;
+ end
+
+ RX_STATE_VALUE16:
+ if ( IsHexDigit )
+ RxValue16 <= { RxValue16[11:0], RxHexValue };
+ else if ( IsWhiteSpace )
+ begin
+ // Done collecting 16-bit value
+ if ( RxWrite )
+ begin
+ // This is a register write
+ if ( RxWrData )
+ begin
+ // Second time around - just received write data
+ DAT_O <= RxValue16;
+ RxState <= RX_STATE_CMD;
+ end
+ else
+ begin
+ // Just received register address - expecting second argument
+ RegAddr <= RxValue16;
+ RxState <= RX_STATE_VALUE16_FIRST;
+ RxWrData <= 1; // Now receive the write data
+ end
+ end
+ else
+ begin
+ // This is a register read
+ RegAddr <= RxValue16;
+ RxState <= RX_STATE_CMD;
+ end
+ end
+ else
+ begin
+ // Unexpected character!
+ TxERROR <= 1;
+ RxState <= RX_STATE_IDLE;
+ end
+
+ default:
+ TxERROR <= 1;
+ endcase
+ end
+ end
+
+endmodule
diff --git a/usrp2/fpga/eth/demo/verilog/tb_demo.v b/usrp2/fpga/eth/demo/verilog/tb_demo.v new file mode 100644 index 000000000..c5a8a3f41 --- /dev/null +++ b/usrp2/fpga/eth/demo/verilog/tb_demo.v @@ -0,0 +1,348 @@ +`timescale 1ns / 1ns
+
+module tb_demo;
+
+ //-------------------- Instantiate Xilinx glbl module ----------------------
+ // - this is needed to get ModelSim to work because e.g. I/O buffer models
+ // refer directly to glbl.GTS and similar signals
+
+ wire GSR;
+ wire GTS;
+ xlnx_glbl glbl( .GSR( GSR ), .GTS( GTS ) );
+
+ reg VLOG_ExitSignal = 0;
+ reg Done = 0;
+ reg Error = 0;
+
+ //-------------------------------------------------------------------------
+
+ reg Reset_n;
+ reg Clk_100M;
+ reg Clk_125M;
+
+ wire RS232_TXD;
+ wire RS232_RXD;
+
+ wire USB_TXD;
+ wire USB_RXD;
+
+ //--- 10/100/1000BASE-T Ethernet PHY (MII/GMII)
+ wire PHY_RESET_n;
+
+ wire PHY_RXC;
+ wire [7:0] PHY_RXD;
+ wire PHY_RXDV;
+ wire PHY_RXER;
+
+ wire PHY_GTX_CLK; // GMII only
+ wire PHY_TXC;
+ wire [7:0] PHY_TXD;
+ wire PHY_TXEN;
+ wire PHY_TXER;
+
+ wire PHY_COL = 0;
+ wire PHY_CRS = 0;
+
+ wire PHY_MDC;
+ wire PHY_MDIO;
+
+ wire [1:4] LED;
+
+ reg [1:4] Button = 4'b0000;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ //-------------------------------------------------------------------------
+ // Instantiation of sub-modules
+ //-------------------------------------------------------------------------
+
+ //--- DUT
+
+ demo demo(
+ .Reset_n ( Reset_n ),
+ .Clk_100M( Clk_100M ),
+ .Clk_125M( Clk_125M ),
+
+ .RS232_TXD( RS232_TXD ),
+ .RS232_RXD( RS232_RXD ),
+
+ .USB_TXD( USB_TXD ),
+ .USB_RXD( USB_RXD ),
+
+ //--- 10/100/1000BASE-T Ethernet PHY (MII/GMII)
+ .PHY_RESET_n( PHY_RESET_n ),
+
+ .PHY_RXC ( PHY_RXC ),
+ .PHY_RXD ( PHY_RXD ),
+ .PHY_RXDV( PHY_RXDV ),
+ .PHY_RXER( PHY_RXER ),
+
+ .PHY_GTX_CLK( PHY_GTX_CLK ), // GMII only
+ .PHY_TXC ( PHY_TXC ),
+ .PHY_TXD ( PHY_TXD ),
+ .PHY_TXEN ( PHY_TXEN ),
+ .PHY_TXER ( PHY_TXER ),
+
+ .PHY_COL( PHY_COL ),
+ .PHY_CRS( PHY_CRS ),
+
+ .PHY_MDC ( PHY_MDC ),
+ .PHY_MDIO( PHY_MDIO ),
+
+ // Misc. I/Os
+ .LED ( LED ),
+ .Button( Button )
+ );
+
+ //-------------------------------------------------------------------------
+ // MII/GMII Ethernet PHY model
+
+ reg [2:0] Speed = 3'b000;
+
+ Phy_sim U_Phy_sim(
+ .Gtx_clk( PHY_GTX_CLK ),
+ .Rx_clk ( PHY_RXC ),
+ .Tx_clk ( PHY_TXC ),
+ .Tx_er ( PHY_TXER ),
+ .Tx_en ( PHY_TXEN ),
+ .Txd ( PHY_TXD ),
+ .Rx_er ( PHY_RXER ),
+ .Rx_dv ( PHY_RXDV ),
+ .Rxd ( PHY_RXD ),
+ .Crs ( PHY_CRS ),
+ .Col ( PHY_COL ),
+ .Speed ( Speed ),
+ .Done ( Done )
+ );
+
+ //-------------------------------------------------------------------------
+ // Generate all clocks & reset
+ //-------------------------------------------------------------------------
+
+ // Core master clock (100 MHz)
+ initial
+ begin
+ #10;
+ while ( !Done )
+ begin
+ #5 Clk_100M = 0;
+ #5 Clk_100M = 1;
+ end
+ end
+
+ // GMII master clock (125 MHz)
+ initial
+ begin
+ #10;
+ while ( !Done )
+ begin
+ #4 Clk_125M = 0;
+ #4 Clk_125M = 1;
+ end
+ end
+
+ initial
+ begin
+ Reset_n = 0;
+
+ #103;
+ Reset_n = 1;
+ end
+
+ //--- Emulate UART Transmitter --------------------------------------------
+
+ parameter PRESCALER_16X = 3;
+ integer Prescaler;
+ integer TxLen = 0;
+ reg [2:0] TxState;
+ integer TxBit;
+ reg [1023:0] TxMsg;
+ reg TXD;
+ reg TxDone;
+
+ always @( negedge Reset_n or posedge Clk_100M )
+ if ( ~Reset_n )
+ begin
+ Prescaler <= 0;
+ TxState = 0;
+ TXD = 1;
+ TxBit = 0;
+ TxDone <= 0;
+ end
+ else
+ begin
+ TxDone <= 0;
+
+ if ( Prescaler == ((PRESCALER_16X + 1)*16 -1) )
+ Prescaler <= 0;
+ else
+ Prescaler <= Prescaler + 1;
+
+ if ( Prescaler==0 )
+ begin
+ casez ( TxState )
+ 0: // IDLE
+ begin
+ if ( TxLen != 0 )
+ begin // Send start bit!
+ TxBit = (TxLen-1)*8;
+ TxLen = TxLen - 1;
+ TXD = 0;
+ TxState = 1;
+ end
+ end
+
+ 1: // Send next data bit
+ begin
+ // Send next data bit
+ TXD = TxMsg[ TxBit ];
+ TxBit = TxBit + 1;
+ if ( (TxBit % 8)==0 )
+ // Next send two stop bits
+ TxState = 2;
+ end
+
+ 2: // First of two stop bits
+ begin
+ TXD = 1;
+ TxState = 3;
+ end
+
+ 3: // Second of two stop bits
+ begin
+ TXD = 1;
+ TxState = 0;
+ if ( TxLen == 0 )
+ // Done with transmission!
+ TxDone <= 1;
+ end
+ endcase
+ end
+ end
+
+ assign RS232_RXD = TXD;
+ assign USB_RXD = 1;
+
+ //--- Send commands to the DUT --------------------------------------------
+
+ initial
+ begin
+ #10;
+ while ( ~Reset_n ) #10;
+
+ // Wait a couple of clock edges before continuing to allow
+ // internal logic to get out of reset
+ repeat ( 5 )
+ @( posedge Clk_100M );
+
+ // Wait for the "READY" message to complete transmission
+ #60000;
+
+ // Select 100 Mbps
+ Speed = 3'b010;
+ TxMsg = "W 0022 0002 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8000 8003 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8001 0011 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8002 1234 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8003 5678 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8004 9ABC ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8005 DEF0 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8006 C5C0 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "W 8007 BABE ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ TxMsg = "R 8006 ";
+ TxLen = 7;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ // Enable PG!
+ TxMsg = "W 1000 0001 ";
+ TxLen = 12;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ // Read back that PG has been enabled!
+ TxMsg = "R 1000 ";
+ TxLen = 7;
+ while ( ~TxDone )
+ @( posedge Clk_100M );
+
+ #50000;
+
+ #50000;
+
+ Done = 1; #10;
+
+ $stop;
+ end
+
+ //--- Directly accesses a register on the internal Wishbone bus, bypassing the UART interface
+
+ task WrReg;
+ input [15:0] Reg;
+ input [15:0] Data;
+
+ begin
+ end
+ endtask
+
+endmodule
diff --git a/usrp2/fpga/eth/header_ram.v b/usrp2/fpga/eth/header_ram.v new file mode 100644 index 000000000..699f16a4f --- /dev/null +++ b/usrp2/fpga/eth/header_ram.v @@ -0,0 +1,24 @@ + +module header_ram + #(parameter REGNUM=0, + parameter WIDTH=32) + (input clk, + input set_stb, + input [7:0] set_addr, + input [31:0] set_data, + + input [3:0] addr, + output [31:0] q + ); + + reg [WIDTH-1:0] mini_ram[0:15]; + wire write_to_ram = (set_stb & (set_addr[7:4]==REGNUM[7:4])); + wire [3:0] ram_addr = write_to_ram ? set_addr[3:0] : addr; + + always @(posedge clk) + if(write_to_ram) + mini_ram[ram_addr] <= set_data; + + assign q = mini_ram[ram_addr]; + +endmodule // header_ram diff --git a/usrp2/fpga/eth/mac_rxfifo_int.v b/usrp2/fpga/eth/mac_rxfifo_int.v new file mode 100644 index 000000000..9393cbd12 --- /dev/null +++ b/usrp2/fpga/eth/mac_rxfifo_int.v @@ -0,0 +1,80 @@ + +module mac_rxfifo_int + (input clk, input rst, + + input Rx_mac_empty, + output Rx_mac_rd, + input [31:0] Rx_mac_data, + input [1:0] Rx_mac_BE, + input Rx_mac_sop, + input Rx_mac_eop, + input Rx_mac_err, + + output [31:0] wr_dat_o, + output wr_write_o, + output wr_done_o, + output wr_error_o, + input wr_ready_i, + input wr_full_i, + + // FIFO Status + output [15:0] fifo_occupied, + output fifo_full, + output fifo_empty + ); + + // Write side of short FIFO + // Inputs: full, Rx_mac_empty, Rx_mac_sop, Rx_mac_eop, Rx_mac_err, Rx_mac_data/BE + // Controls: write, datain, Rx_mac_rd + + wire write, full, read, empty, sop_o, eop_o, error_o; + + // Write side of short FIFO + assign write = ~full & ~Rx_mac_empty; + assign Rx_mac_rd = write; + + shortfifo #(.WIDTH(35)) mac_rx_sfifo + (.clk(clk),.rst(rst),.clear(0), + .datain({Rx_mac_sop,Rx_mac_eop,Rx_mac_err,Rx_mac_data}),.write(write),.full(full), + .dataout({sop_o,eop_o,error_o,wr_dat_o}),.read(read),.empty(empty), + .space(), .occupied(fifo_occupied[4:0]) ); + assign fifo_occupied[15:5] = 0; + assign fifo_full = full; + assign fifo_empty = empty; + + // Read side of short FIFO + // Inputs: empty, dataout, wr_ready_i, wr_full_i + // Controls: read, wr_dat_o, wr_write_o, wr_done_o, wr_error_o + + reg [1:0] rd_state; + localparam RD_IDLE = 0; + localparam RD_HAVEPKT = 1; + localparam RD_XFER = 2; + localparam RD_ERROR = 3; + + always @(posedge clk) + if(rst) + rd_state <= RD_IDLE; + else + case(rd_state) + RD_IDLE : + if(sop_o & ~empty) + rd_state <= RD_HAVEPKT; + RD_HAVEPKT : + if(wr_ready_i) + rd_state <= RD_XFER; + RD_XFER : + if(eop_o & ~empty) + rd_state <= RD_IDLE; + else if(wr_full_i) + rd_state <= RD_HAVEPKT; + RD_ERROR : + rd_state <= RD_IDLE; + endcase // case(rd_state) + + assign read = ~empty & ((rd_state == RD_XFER) | ((rd_state==RD_IDLE)&~sop_o)); + assign wr_write_o = ~empty & (rd_state == RD_XFER); + assign wr_done_o = ~empty & (rd_state == RD_XFER) & eop_o; + assign wr_error_o = ~empty & (rd_state == RD_XFER) & error_o; + +endmodule // mac_rxfifo_int diff --git a/usrp2/fpga/eth/mac_txfifo_int.v b/usrp2/fpga/eth/mac_txfifo_int.v new file mode 100644 index 000000000..38d8d38fc --- /dev/null +++ b/usrp2/fpga/eth/mac_txfifo_int.v @@ -0,0 +1,77 @@ + +module mac_txfifo_int + (input clk, input rst, input mac_clk, + + // To MAC + input Tx_mac_wa, + output Tx_mac_wr, + output [31:0] Tx_mac_data, + output [1:0] Tx_mac_BE, + output Tx_mac_sop, + output Tx_mac_eop, + + // To buffer interface + input [31:0] rd_dat_i, + output rd_read_o, + output rd_done_o, + output rd_error_o, + input rd_sop_i, + input rd_eop_i, + + // FIFO Status + output [15:0] fifo_occupied, + output fifo_full, + output fifo_empty ); + + wire empty, full, sfifo_write, sfifo_read; + wire [33:0] sfifo_in, sfifo_out; + + /* + shortfifo #(.WIDTH(34)) txmac_sfifo + (.clk(clk),.rst(rst),.clear(0), + .datain(sfifo_in),.write(sfifo_write),.full(full), + .dataout(sfifo_out),.read(sfifo_read),.empty(empty)); + */ + fifo_xlnx_512x36_2clk mac_tx_fifo_2clk + (.rst(rst), + .wr_clk(clk),.din({2'b0,sfifo_in}),.full(full),.wr_en(sfifo_write),.wr_data_count(fifo_occupied[8:0]), + .rd_clk(mac_clk),.dout(sfifo_out),.empty(empty),.rd_en(sfifo_read),.rd_data_count() ); + assign fifo_occupied[15:9] = 0; + assign fifo_full = full; + assign fifo_empty = empty; // Note empty is in wrong clock domain + + // MAC side signals + // We are allowed to do one more write after we are told the FIFO is full + // This allows us to register the _wa signal and speed up timing. + + reg tx_mac_wa_d1; + always @(posedge clk) + tx_mac_wa_d1 <= Tx_mac_wa; + + assign sfifo_read = ~empty & tx_mac_wa_d1; + + assign Tx_mac_wr = sfifo_read; + assign Tx_mac_data = sfifo_out[31:0]; + assign Tx_mac_BE = 0; // Since we only deal with packets that are multiples of 32 bits long + assign Tx_mac_sop = sfifo_out[33]; + assign Tx_mac_eop = sfifo_out[32]; + + + // BUFFER side signals + reg xfer_active; + always @(posedge clk) + if(rst) + xfer_active <= 0; + else if(rd_eop_i & ~full) + xfer_active <= 0; + else if(rd_sop_i) + xfer_active <= 1; + + assign sfifo_in = {rd_sop_i, rd_eop_i, rd_dat_i}; + assign sfifo_write = xfer_active & ~full; + + assign rd_read_o = sfifo_write; + assign rd_done_o = 0; // Always send everything we're given? + assign rd_error_o = 0; // No possible error situations? + +endmodule // mac_txfifo_int diff --git a/usrp2/fpga/eth/rtl/verilog/Clk_ctrl.v b/usrp2/fpga/eth/rtl/verilog/Clk_ctrl.v new file mode 100644 index 000000000..917082644 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/Clk_ctrl.v @@ -0,0 +1,133 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// Clk_ctrl.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: Clk_ctrl.v,v $
+// Revision 1.3 2006/01/19 14:07:52 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:13 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+module Clk_ctrl(
+Reset ,
+Clk_125M ,
+//host interface,
+Speed ,
+//Phy interface ,
+Gtx_clk ,
+Rx_clk ,
+Tx_clk ,
+//interface clk ,
+MAC_tx_clk ,
+MAC_rx_clk ,
+MAC_tx_clk_div ,
+MAC_rx_clk_div
+);
+input Reset ;
+input Clk_125M ;
+ //host interface
+input [2:0] Speed ;
+ //Phy interface
+output Gtx_clk ;//used only in GMII mode
+input Rx_clk ;
+input Tx_clk ;//used only in MII mode
+ //interface clk signals
+output MAC_tx_clk ;
+output MAC_rx_clk ;
+output MAC_tx_clk_div ;
+output MAC_rx_clk_div ;
+
+
+// ******************************************************************************
+// internal signals
+// ******************************************************************************
+wire Rx_clk_div2 ;
+wire Tx_clk_div2 ;
+// ******************************************************************************
+//
+// ******************************************************************************
+ assign Gtx_clk = Clk_125M ;
+ assign MAC_rx_clk = Rx_clk ;
+ assign MAC_rx_clk_div = Rx_clk ;
+ assign MAC_tx_clk = Clk_125M;
+ assign MAC_tx_clk_div = Clk_125M;
+
+
+ /*
+eth_clk_div2 U_0_CLK_DIV2(
+.Reset (Reset ),
+.IN (Rx_clk ),
+.OUT (Rx_clk_div2 )
+);
+
+eth_clk_div2 U_1_CLK_DIV2(
+.Reset (Reset ),
+.IN (Tx_clk ),
+.OUT (Tx_clk_div2 )
+);
+
+eth_clk_switch U_0_CLK_SWITCH(
+.IN_0 (Rx_clk_div2 ),
+.IN_1 (Rx_clk ),
+.SW (Speed[2] ),
+.OUT (MAC_rx_clk_div )
+);
+
+eth_clk_switch U_1_CLK_SWITCH(
+.IN_0 (Tx_clk ),
+.IN_1 (Clk_125M ),
+.SW (Speed[2] ),
+.OUT (MAC_tx_clk )
+);
+
+eth_clk_switch U_2_CLK_SWITCH(
+.IN_0 (Tx_clk_div2 ),
+.IN_1 (Clk_125M ),
+.SW (Speed[2] ),
+.OUT (MAC_tx_clk_div )
+);
+
+ */
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_rx.v b/usrp2/fpga/eth/rtl/verilog/MAC_rx.v new file mode 100644 index 000000000..0e02e8fcc --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_rx.v @@ -0,0 +1,242 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// MAC_rx.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: MAC_rx.v,v $
+// Revision 1.4 2006/11/17 17:53:07 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:52 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:13 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+module MAC_rx
+ #(parameter RX_FF_DEPTH = 9)
+ (
+input Reset ,
+input Clk_user,
+input Clk ,
+ //RMII interface
+input MCrs_dv ,
+input [7:0] MRxD ,
+input MRxErr ,
+ //flow_control signals
+output [15:0] pause_quanta,
+output pause_quanta_val,
+output [15:0] rx_fifo_space,
+ //user interface
+output Rx_mac_empty,
+input Rx_mac_rd ,
+output [31:0] Rx_mac_data ,
+output [1:0] Rx_mac_BE ,
+output Rx_mac_sop ,
+output Rx_mac_eop ,
+output Rx_mac_err ,
+ //CPU
+input MAC_rx_add_chk_en ,
+input [7:0] MAC_add_prom_data ,
+input [2:0] MAC_add_prom_add ,
+input MAC_add_prom_wr ,
+input broadcast_filter_en ,
+input [15:0] broadcast_bucket_depth ,
+input [15:0] broadcast_bucket_interval ,
+input RX_APPEND_CRC,
+input [4:0] Rx_Hwmark ,
+input [4:0] Rx_Lwmark ,
+input CRC_chk_en ,
+input [5:0] RX_IFG_SET ,
+input [15:0] RX_MAX_LENGTH ,// 1518
+input [6:0] RX_MIN_LENGTH ,// 64
+ //RMON interface
+output [15:0] Rx_pkt_length_rmon ,
+output Rx_apply_rmon ,
+output [2:0] Rx_pkt_err_type_rmon ,
+output [2:0] Rx_pkt_type_rmon ,
+
+ output [15:0] rx_fifo_occupied,
+ output rx_fifo_full,
+ output rx_fifo_empty,
+ output [31:0] debug
+);
+//******************************************************************************
+//internal signals
+//******************************************************************************
+ //CRC_chk interface
+wire CRC_en ;
+wire [7:0] CRC_data;
+wire CRC_init;
+wire CRC_err ;
+ //MAC_rx_add_chk interface
+wire MAC_add_en ;
+wire [7:0] MAC_add_data;
+wire MAC_rx_add_chk_err ;
+ //broadcast_filter
+wire broadcast_ptr ;
+wire broadcast_drop ;
+ //MAC_rx_ctrl interface
+wire [7:0] Fifo_data ;
+wire Fifo_data_en ;
+wire Fifo_full ;
+wire Fifo_data_err ;
+wire Fifo_data_drop ;
+wire Fifo_data_end ;
+
+
+//******************************************************************************
+//instantiation
+//******************************************************************************
+
+
+MAC_rx_ctrl U_MAC_rx_ctrl(
+.Reset (Reset ),
+.Clk (Clk ),
+ //RMII interface ( //RMII interface ),
+.MCrs_dv (MCrs_dv ),
+.MRxD (MRxD ),
+.MRxErr (MRxErr ),
+ //CRC_chk interface (//CRC_chk interface ),
+.CRC_en (CRC_en ),
+.CRC_data (CRC_data ),
+.CRC_init (CRC_init ),
+.CRC_err (CRC_err ),
+ //MAC_rx_add_chk interface (//MAC_rx_add_chk interface),
+.MAC_add_en (MAC_add_en ),
+.MAC_add_data (MAC_add_data ),
+.MAC_rx_add_chk_err (MAC_rx_add_chk_err ),
+ //broadcast_filter (//broadcast_filter ),
+.broadcast_ptr (broadcast_ptr ),
+.broadcast_drop (broadcast_drop ),
+ //flow_control signals (//flow_control signals ),
+.pause_quanta (pause_quanta ),
+.pause_quanta_val (pause_quanta_val ),
+ //MAC_rx_FF interface (//MAC_rx_FF interface ),
+.Fifo_data (Fifo_data ),
+.Fifo_data_en (Fifo_data_en ),
+.Fifo_data_err (Fifo_data_err ),
+.Fifo_data_drop (Fifo_data_drop ),
+.Fifo_data_end (Fifo_data_end ),
+.Fifo_full (Fifo_full ),
+ //RMON interface (//RMON interface ),
+.Rx_pkt_type_rmon (Rx_pkt_type_rmon ),
+.Rx_pkt_length_rmon (Rx_pkt_length_rmon ),
+.Rx_apply_rmon (Rx_apply_rmon ),
+.Rx_pkt_err_type_rmon (Rx_pkt_err_type_rmon ),
+ //CPU (//CPU ),
+.RX_IFG_SET (RX_IFG_SET ),
+.RX_MAX_LENGTH (RX_MAX_LENGTH ),
+.RX_MIN_LENGTH (RX_MIN_LENGTH )
+);
+
+ assign debug = {28'd0, Fifo_data_en, Fifo_data_err, Fifo_data_end,Fifo_full};
+
+MAC_rx_FF #(.RX_FF_DEPTH(RX_FF_DEPTH)) U_MAC_rx_FF (
+.Reset (Reset ),
+.Clk_MAC (Clk ),
+.Clk_SYS (Clk_user ),
+ //MAC_rx_ctrl interface (//MAC_rx_ctrl interface ),
+.Fifo_data (Fifo_data ),
+.Fifo_data_en (Fifo_data_en ),
+.Fifo_full (Fifo_full ),
+.Fifo_data_err (Fifo_data_err ),
+//.Fifo_data_drop (Fifo_data_drop ),
+.Fifo_data_end (Fifo_data_end ),
+.Fifo_space (rx_fifo_space ),
+ //CPU (//CPU ),
+.Rx_Hwmark (Rx_Hwmark ),
+.Rx_Lwmark (Rx_Lwmark ),
+.RX_APPEND_CRC (RX_APPEND_CRC ),
+ //user interface (//user interface ),
+.Rx_mac_empty (Rx_mac_empty ),
+.Rx_mac_rd (Rx_mac_rd ),
+.Rx_mac_data (Rx_mac_data ),
+.Rx_mac_BE (Rx_mac_BE ),
+.Rx_mac_sop (Rx_mac_sop ),
+.Rx_mac_eop (Rx_mac_eop ),
+.Rx_mac_err (Rx_mac_err ),
+
+.fifo_occupied(rx_fifo_occupied),
+.fifo_full_dbg(rx_fifo_full),
+.fifo_empty(rx_fifo_empty)
+);
+
+ Broadcast_filter U_Broadcast_filter
+ (.Reset (Reset ),
+ .Clk (Clk ),
+ //MAC_rx_ctrl (//MAC_rx_ctrl ),
+ .broadcast_ptr (broadcast_ptr ),
+ .broadcast_drop (broadcast_drop ),
+ //FromCPU (//FromCPU ),
+ .broadcast_filter_en (broadcast_filter_en ),
+ .broadcast_bucket_depth (broadcast_bucket_depth ),
+ .broadcast_bucket_interval (broadcast_bucket_interval )
+ );
+
+CRC_chk U_CRC_chk(
+.Reset (Reset ),
+.Clk (Clk ),
+.CRC_data (CRC_data ),
+.CRC_init (CRC_init ),
+.CRC_en (CRC_en ),
+ //From CPU (//From CPU ),
+.CRC_chk_en (CRC_chk_en ),
+.CRC_err (CRC_err )
+);
+
+ MAC_rx_add_chk U_MAC_rx_add_chk
+ (.Reset (Reset ),
+ .Clk (Clk ),
+ .Init (CRC_init ),
+ .data (MAC_add_data ),
+ .MAC_add_en (MAC_add_en ),
+ .MAC_rx_add_chk_err (MAC_rx_add_chk_err ),
+ //From CPU (//From CPU ),
+ .MAC_rx_add_chk_en (MAC_rx_add_chk_en ),
+ .MAC_add_prom_data (MAC_add_prom_data ),
+ .MAC_add_prom_add (MAC_add_prom_add ),
+ .MAC_add_prom_wr (MAC_add_prom_wr )
+ );
+
+endmodule // MAC_rx
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_rx/Broadcast_filter.v b/usrp2/fpga/eth/rtl/verilog/MAC_rx/Broadcast_filter.v new file mode 100644 index 000000000..bc95e31d7 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_rx/Broadcast_filter.v @@ -0,0 +1,107 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// Broadcast_filter.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: Broadcast_filter.v,v $
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:16 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module Broadcast_filter (
+Reset ,
+Clk ,
+//MAC_rx_ctrl ,
+broadcast_ptr ,
+broadcast_drop ,
+//FromCPU ,
+broadcast_filter_en ,
+broadcast_bucket_depth ,
+broadcast_bucket_interval
+);
+input Reset ;
+input Clk ;
+ //MAC_rx_ctrl
+input broadcast_ptr ;
+output broadcast_drop ;
+ //FromCPU ;
+input broadcast_filter_en ;
+input [15:0] broadcast_bucket_depth ;
+input [15:0] broadcast_bucket_interval ;
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+reg [15:0] time_counter ;
+reg [15:0] broadcast_counter ;
+reg broadcast_drop ;
+//******************************************************************************
+//
+//******************************************************************************
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ time_counter <=0;
+ else if (time_counter==broadcast_bucket_interval)
+ time_counter <=0;
+ else
+ time_counter <=time_counter+1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ broadcast_counter <=0;
+ else if (time_counter==broadcast_bucket_interval)
+ broadcast_counter <=0;
+ else if (broadcast_ptr&&broadcast_counter!=broadcast_bucket_depth)
+ broadcast_counter <=broadcast_counter+1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ broadcast_drop <=0;
+ else if(broadcast_filter_en&&broadcast_counter==broadcast_bucket_depth)
+ broadcast_drop <=1;
+ else
+ broadcast_drop <=0;
+
+endmodule
\ No newline at end of file diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_rx/CRC_chk.v b/usrp2/fpga/eth/rtl/verilog/MAC_rx/CRC_chk.v new file mode 100644 index 000000000..d6bb22b51 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_rx/CRC_chk.v @@ -0,0 +1,128 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// CRC_chk.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: CRC_chk.v,v $
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:16 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module CRC_chk(
+Reset ,
+Clk ,
+CRC_data ,
+CRC_init ,
+CRC_en ,
+//From CPU
+CRC_chk_en ,
+CRC_err
+);
+input Reset ;
+input Clk ;
+input[7:0] CRC_data ;
+input CRC_init ;
+input CRC_en ;
+ //From CPU
+input CRC_chk_en ;
+output CRC_err ;
+//******************************************************************************
+//internal signals
+//******************************************************************************
+reg [31:0] CRC_reg;
+//******************************************************************************
+//input data width is 8bit, and the first bit is bit[0]
+function[31:0] NextCRC;
+ input[7:0] D;
+ input[31:0] C;
+ reg[31:0] NewCRC;
+ begin
+ NewCRC[0]=C[24]^C[30]^D[1]^D[7];
+ NewCRC[1]=C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[2]=C[26]^D[5]^C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[3]=C[27]^D[4]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[4]=C[28]^D[3]^C[27]^D[4]^C[26]^D[5]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[5]=C[29]^D[2]^C[28]^D[3]^C[27]^D[4]^C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[6]=C[30]^D[1]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[7]=C[31]^D[0]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[24]^D[7];
+ NewCRC[8]=C[0]^C[28]^D[3]^C[27]^D[4]^C[25]^D[6]^C[24]^D[7];
+ NewCRC[9]=C[1]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^D[6];
+ NewCRC[10]=C[2]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[24]^D[7];
+ NewCRC[11]=C[3]^C[28]^D[3]^C[27]^D[4]^C[25]^D[6]^C[24]^D[7];
+ NewCRC[12]=C[4]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[13]=C[5]^C[30]^D[1]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[14]=C[6]^C[31]^D[0]^C[30]^D[1]^C[28]^D[3]^C[27]^D[4]^C[26]^D[5];
+ NewCRC[15]=C[7]^C[31]^D[0]^C[29]^D[2]^C[28]^D[3]^C[27]^D[4];
+ NewCRC[16]=C[8]^C[29]^D[2]^C[28]^D[3]^C[24]^D[7];
+ NewCRC[17]=C[9]^C[30]^D[1]^C[29]^D[2]^C[25]^D[6];
+ NewCRC[18]=C[10]^C[31]^D[0]^C[30]^D[1]^C[26]^D[5];
+ NewCRC[19]=C[11]^C[31]^D[0]^C[27]^D[4];
+ NewCRC[20]=C[12]^C[28]^D[3];
+ NewCRC[21]=C[13]^C[29]^D[2];
+ NewCRC[22]=C[14]^C[24]^D[7];
+ NewCRC[23]=C[15]^C[25]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[24]=C[16]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[25]=C[17]^C[27]^D[4]^C[26]^D[5];
+ NewCRC[26]=C[18]^C[28]^D[3]^C[27]^D[4]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[27]=C[19]^C[29]^D[2]^C[28]^D[3]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[28]=C[20]^C[30]^D[1]^C[29]^D[2]^C[26]^D[5];
+ NewCRC[29]=C[21]^C[31]^D[0]^C[30]^D[1]^C[27]^D[4];
+ NewCRC[30]=C[22]^C[31]^D[0]^C[28]^D[3];
+ NewCRC[31]=C[23]^C[29]^D[2];
+ NextCRC=NewCRC;
+ end
+ endfunction
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ CRC_reg <=32'hffffffff;
+ else if (CRC_init)
+ CRC_reg <=32'hffffffff;
+ else if (CRC_en)
+ CRC_reg <=NextCRC(CRC_data,CRC_reg);
+
+assign CRC_err = CRC_chk_en&(CRC_reg[31:0] != 32'hc704dd7b);
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v b/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v new file mode 100644 index 000000000..e212b8986 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v @@ -0,0 +1,167 @@ +
+// ////////////////////////////////////////////////////////////////////
+// Completely Rewritten by M. Ettus, no John Gao code left
+// ////////////////////////////////////////////////////////////////////
+
+module MAC_rx_FF
+ #(parameter RX_FF_DEPTH = 9)
+ (input Reset,
+ input Clk_MAC,
+ input Clk_SYS,
+
+ // MAC_rx_ctrl interface
+ input [7:0] Fifo_data,
+ input Fifo_data_en,
+ output Fifo_full,
+ input Fifo_data_err,
+ input Fifo_data_end,
+ output [15:0] Fifo_space,
+
+ // CPU
+ input RX_APPEND_CRC,
+ input [4:0] Rx_Hwmark,
+ input [4:0] Rx_Lwmark,
+
+ // User interface
+ output Rx_mac_empty,
+ input Rx_mac_rd,
+ output [31:0] Rx_mac_data,
+ output [1:0] Rx_mac_BE,
+ output Rx_mac_sop,
+ output Rx_mac_eop,
+ output Rx_mac_err,
+
+ // FIFO Levels
+ output [15:0] fifo_occupied,
+ output fifo_full_dbg,
+ output fifo_empty
+ );
+
+ reg [1:0] FF_state;
+ reg [2:0] PKT_state;
+ reg [31:0] staging;
+ reg [35:0] staging2;
+ reg line_ready, line_ready_d1;
+ wire sop_i, eop_i;
+ reg [1:0] be;
+
+ always @(posedge Clk_MAC or posedge Reset)
+ if(Reset)
+ FF_state <= 0;
+ else
+ if(Fifo_data_err | Fifo_data_end)
+ FF_state <= 0;
+ else if(Fifo_data_en)
+ FF_state <= FF_state + 1;
+
+ always @(posedge Clk_MAC or posedge Reset)
+ if(Reset)
+ staging[31:0] <= 0;
+ else if(Fifo_data_en)
+ case(FF_state)
+ 0 : staging[31:24] <= Fifo_data;
+ 1 : staging[23:16] <= Fifo_data;
+ 2 : staging[15:8] <= Fifo_data;
+ 3 : staging[7:0] <= Fifo_data;
+ endcase // case(FF_state)
+
+ localparam PKT_idle = 0;
+ localparam PKT_sop = 1;
+ localparam PKT_pkt = 2;
+ localparam PKT_end = 3;
+ localparam PKT_err = 4;
+
+ always @(posedge Clk_MAC or posedge Reset)
+ if(Reset)
+ PKT_state <= 0;
+ else
+ case(PKT_state)
+ PKT_idle :
+ if(Fifo_data_en)
+ PKT_state <= PKT_sop;
+ PKT_sop, PKT_pkt :
+ if(Fifo_data_err | (line_ready & Fifo_full))
+ PKT_state <= PKT_err;
+ else if(Fifo_data_end)
+ PKT_state <= PKT_end;
+ else if(line_ready & ~Fifo_full)
+ PKT_state <= PKT_pkt;
+ PKT_end :
+ PKT_state <= PKT_idle;
+ PKT_err :
+ if(~Fifo_full)
+ PKT_state <= PKT_idle;
+ endcase // case(PKT_state)
+
+ assign sop_i = (PKT_state == PKT_sop);
+ assign eop_i = (PKT_state == PKT_end);
+
+ always @(posedge Clk_MAC)
+ if(line_ready)
+ staging2 <= {sop_i, eop_i, be[1:0], staging};
+
+ always @(posedge Clk_MAC)
+ if(Reset)
+ line_ready <= 0;
+ else if((Fifo_data_en & (FF_state==2'd3)) | Fifo_data_end | Fifo_data_err)
+ line_ready <= 1;
+ else
+ line_ready <= 0;
+
+ always @(posedge Clk_MAC)
+ line_ready_d1 <= line_ready;
+
+ always @(posedge Clk_MAC)
+ if(Fifo_data_end | Fifo_data_err)
+ be <= FF_state;
+ else
+ be <= 0;
+
+ wire sop_o, eop_o, empty;
+ wire [1:0] be_o;
+ wire [RX_FF_DEPTH-1:0] occupied, occupied_sysclk;
+ wire [31:0] dataout;
+
+/*
+ fifo_2clock #(.DWIDTH(36),.AWIDTH(RX_FF_DEPTH)) mac_rx_fifo
+ (.wclk(Clk_MAC),.datain((PKT_state==PKT_err) ? 36'hF_FFFF_FFFF : staging2),.write(~Fifo_full & (line_ready_d1|(PKT_state==PKT_err))),
+ .full(Fifo_full),.level_wclk(occupied),
+ .rclk(Clk_SYS),.dataout({sop_o,eop_o,be_o[1:0],dataout}),.read(Rx_mac_rd),
+ .empty(empty),.level_rclk(),
+ .arst(Reset) );
+ */
+
+ fifo_xlnx_2Kx36_2clk mac_rx_ff_core
+ (
+ .din((PKT_state==PKT_err) ? 36'hF_FFFF_FFFF : staging2), // Bus [35 : 0]
+ .rd_clk(Clk_SYS),
+ .rd_en(Rx_mac_rd),
+ .rst(Reset),
+ .wr_clk(Clk_MAC),
+ .wr_en(~Fifo_full & (line_ready_d1|(PKT_state==PKT_err))),
+ .dout({sop_o,eop_o,be_o[1:0],dataout}), // Bus [35 : 0]
+ .empty(empty),
+ .full(Fifo_full),
+ .rd_data_count(occupied_sysclk), // Bus [11 : 0]
+ .wr_data_count(occupied)); // Bus [11 : 0]
+
+ assign Fifo_space[15:RX_FF_DEPTH] = 0;
+ assign Fifo_space[RX_FF_DEPTH-1:0] = ~occupied;
+ assign fifo_occupied = occupied_sysclk;
+ assign fifo_full_dbg = Fifo_full; // FIXME -- in wrong clock domain
+ assign fifo_empty = empty;
+
+ // mac side fifo interface
+ // Input - Rx_mac_rd
+ // Output - Rx_mac_empty, Rx_mac_sop, Rx_mac_eop, Rx_mac_err, Rx_mac_data, Rx_mac_BE
+
+ assign Rx_mac_BE = be_o;
+ assign Rx_mac_sop = sop_o & ~eop_o;
+ assign Rx_mac_eop = eop_o;
+ assign Rx_mac_err = sop_o & eop_o;
+ assign Rx_mac_empty = empty;
+ assign Rx_mac_data = dataout;
+
+endmodule // MAC_rx_FF
+
+// FIXME Should we send out an "almost full" signal instead of full?
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v b/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v new file mode 100644 index 000000000..0c8d6bd4e --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v @@ -0,0 +1,158 @@ +// ////////////////////////////////////////////////////////////////////
+// // ////
+// // MAC_rx_add_chk.v ////
+// // ////
+// // This file is part of the Ethernet IP core project ////
+// // http://www.opencores.org/projects.cgi/wr_en/ethernet_tri_mode/////
+// // ////
+// // Author(s): ////
+// // - Jon Gao (gaojon@yahoo.com) ////
+// // ////
+// // ////
+// ////////////////////////////////////////////////////////////////////
+// // ////
+// // Copyright (C) 2001 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: MAC_rx_add_chk.v,v $
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:17 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module MAC_rx_add_chk
+ (Reset ,
+ Clk ,
+ Init ,
+ data ,
+ MAC_add_en ,
+ MAC_rx_add_chk_err ,
+ //From CPU
+ MAC_rx_add_chk_en ,
+ MAC_add_prom_data ,
+ MAC_add_prom_add ,
+ MAC_add_prom_wr
+ );
+
+ input Reset ;
+ input Clk ;
+ input Init ;
+ input [7:0] data ;
+ input MAC_add_en ;
+ output MAC_rx_add_chk_err ;
+ //From CPU
+ input MAC_rx_add_chk_en ;
+ input [7:0] MAC_add_prom_data ;
+ input [2:0] MAC_add_prom_add ;
+ input MAC_add_prom_wr ;
+
+ // ******************************************************************************
+ // internal signals
+ // ******************************************************************************
+ reg [2:0] addr_rd;
+ wire [2:0] addr_wr;
+ wire [7:0] din;
+ //wire [7:0] dout;
+ reg [7:0] dout;
+ wire wr_en;
+
+ reg MAC_rx_add_chk_err;
+ reg MAC_add_prom_wr_dl1;
+ reg MAC_add_prom_wr_dl2;
+ reg [7:0] data_dl1 ;
+ reg MAC_add_en_dl1 ;
+
+ // ******************************************************************************
+ // write data from cpu to prom
+ // ******************************************************************************
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ data_dl1 <=0;
+ MAC_add_en_dl1 <=0;
+ end
+ else
+ begin
+ data_dl1 <=data;
+ MAC_add_en_dl1 <=MAC_add_en;
+ end
+
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ MAC_add_prom_wr_dl1 <=0;
+ MAC_add_prom_wr_dl2 <=0;
+ end
+ else
+ begin
+ MAC_add_prom_wr_dl1 <=MAC_add_prom_wr;
+ MAC_add_prom_wr_dl2 <=MAC_add_prom_wr_dl1;
+ end
+
+ assign wr_en =MAC_add_prom_wr_dl1&!MAC_add_prom_wr_dl2;
+ assign addr_wr =MAC_add_prom_add;
+ assign din =MAC_add_prom_data;
+
+ // ******************************************************************************
+ // mac add verify
+ // ******************************************************************************
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ addr_rd <=0;
+ else if (Init)
+ addr_rd <=0;
+ else if (MAC_add_en)
+ addr_rd <=addr_rd + 1;
+
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ MAC_rx_add_chk_err <=0;
+ else if (Init)
+ MAC_rx_add_chk_err <=0;
+ else if (MAC_rx_add_chk_en && MAC_add_en_dl1 && (dout!=data_dl1) )
+ MAC_rx_add_chk_err <=1;
+
+
+ // ******************************************************************************
+ // a port for read ,b port for write .
+ // ******************************************************************************
+
+ reg [7:0] address_ram [0:7];
+ always @(posedge Clk)
+ if(wr_en)
+ address_ram[addr_wr] <= din;
+
+ always @(posedge Clk)
+ dout <= address_ram[addr_rd];
+
+endmodule // MAC_rx_add_chk
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v b/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v new file mode 100644 index 000000000..5ab795801 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v @@ -0,0 +1,664 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// MAC_rx_ctrl.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: MAC_rx_ctrl.v,v $
+// Revision 1.4 2006/06/25 04:58:56 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.3 2005/12/16 06:44:17 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.2 2005/12/13 12:15:37 Administrator
+// no message
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module MAC_rx_ctrl (
+Reset ,
+Clk ,
+//RMII interface
+MCrs_dv , //
+MRxD , //
+MRxErr , //
+//CRC_chk interface
+CRC_en ,
+CRC_data,
+CRC_init ,
+CRC_err ,
+//MAC_rx_add_chk interface
+MAC_add_en ,
+MAC_add_data,
+MAC_rx_add_chk_err ,
+//broadcast_filter
+broadcast_ptr ,
+broadcast_drop ,
+//flow_control signals
+pause_quanta ,
+pause_quanta_val ,
+//MAC_rx_FF interface
+Fifo_data ,
+Fifo_data_en ,
+Fifo_data_err ,
+Fifo_data_drop ,
+Fifo_data_end ,
+Fifo_full ,
+//RMON interface
+Rx_pkt_type_rmon ,
+Rx_pkt_length_rmon ,
+Rx_apply_rmon ,
+Rx_pkt_err_type_rmon ,
+//CPU
+RX_IFG_SET ,
+RX_MAX_LENGTH,
+RX_MIN_LENGTH
+);
+
+input Reset ;
+input Clk ;
+ //RMII interface
+input MCrs_dv ;
+input [7:0] MRxD ;
+input MRxErr ;
+ //CRC_chk interface
+output CRC_en ;
+output CRC_init;
+output [7:0] CRC_data;
+input CRC_err ;
+ //MAC_rx_add_chk interface
+output MAC_add_en ;
+output [7:0] MAC_add_data;
+input MAC_rx_add_chk_err ;
+ //broadcast_filter
+output broadcast_ptr ;
+input broadcast_drop ;
+ //flow_control signals
+output [15:0] pause_quanta ;
+output pause_quanta_val ;
+ //MAC_rx_FF interface
+output [7:0] Fifo_data ;
+output Fifo_data_en ;
+output Fifo_data_err ;
+output Fifo_data_drop ;
+output Fifo_data_end ;
+input Fifo_full;
+ //RMON interface
+output [15:0] Rx_pkt_length_rmon ;
+output Rx_apply_rmon ;
+output [2:0] Rx_pkt_err_type_rmon ;
+output [2:0] Rx_pkt_type_rmon ;
+ //CPU
+input [5:0] RX_IFG_SET ;
+input [15:0] RX_MAX_LENGTH ;// 1518
+input [6:0] RX_MIN_LENGTH ;// 64
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+parameter State_idle =4'd00;
+parameter State_preamble =4'd01;
+parameter State_SFD =4'd02;
+parameter State_data =4'd03;
+parameter State_checkCRC =4'd04;
+parameter State_OkEnd =4'd07;
+parameter State_DropEnd =4'd08;
+parameter State_ErrEnd =4'd09;
+parameter State_CRCErrEnd =4'd10;
+parameter State_FFFullDrop =4'd11;
+parameter State_FFFullErrEnd =4'd12;
+parameter State_IFG =4'd13;
+parameter State_Drop2End =4'd14;
+
+parameter Pause_idle =4'd0;
+parameter Pause_pre_syn =4'd1;
+parameter Pause_quanta_hi =4'd2;
+parameter Pause_quanta_lo =4'd3;
+parameter Pause_syn =4'd4;
+
+reg [3:0] Current_state /* synthesis syn_keep=1 */;
+reg [3:0] Next_state;
+reg [3:0] Pause_current /* synthesis syn_keep=1 */;
+reg [3:0] Pause_next;
+reg [5:0] IFG_counter;
+reg Crs_dv ;
+reg [7:0] RxD ;
+reg [7:0] RxD_dl1 ;
+reg RxErr ;
+reg [15:0] Frame_length_counter;
+reg Too_long;
+reg Too_short;
+reg ProcessingHeader;
+//reg Fifo_data_en;
+//reg Fifo_data_err;
+//reg Fifo_data_drop;
+//reg Fifo_data_end;
+reg CRC_en;
+reg CRC_init;
+reg Rx_apply_rmon;
+reg [2:0] Rx_pkt_err_type_rmon;
+reg MAC_add_en;
+reg [2:0] Rx_pkt_type_rmon;
+reg [7:0] pause_quanta_h ;
+reg [15:0] pause_quanta ;
+reg pause_quanta_val ;
+reg pause_quanta_val_tmp;
+reg pause_frame_ptr ;
+reg broadcast_ptr ;
+//******************************************************************************
+//delay signals
+//******************************************************************************
+
+always @ (posedge Reset or posedge Clk)
+ if (Reset)
+ begin
+ Crs_dv <=0;
+ RxD <=0;
+ RxErr <=0;
+ end
+ else
+ begin
+ Crs_dv <=MCrs_dv ;
+ RxD <=MRxD ;
+ RxErr <=MRxErr ;
+ end
+
+always @ (posedge Reset or posedge Clk)
+ if (Reset)
+ RxD_dl1 <=0;
+ else
+ RxD_dl1 <=RxD;
+
+//---------------------------------------------------------------------------
+// Small pre-FIFO (acutally a synchronously clearable shift-register) for
+// storing the first part of a packet before writing it to the "real" FIFO
+// in MAC_rx_FF. This allows a packet to be dropped safely if an error
+// happens in the beginning of a packet (or if the MAC address doesn't pass
+// the receive filter!)
+//---------------------------------------------------------------------------
+
+ reg pre_fifo_data_drop;
+ reg pre_fifo_data_en;
+ reg pre_fifo_data_err;
+ reg pre_fifo_data_end;
+ wire [7:0] pre_fifo_wrdata;
+
+ reg [8+3-1:0] pre_fifo_element_0;
+ reg [8+3-1:0] pre_fifo_element_1;
+ reg [8+3-1:0] pre_fifo_element_2;
+ reg [8+3-1:0] pre_fifo_element_3;
+ reg [8+3-1:0] pre_fifo_element_4;
+ reg [8+3-1:0] pre_fifo_element_5;
+ reg [8+3-1:0] pre_fifo_element_6;
+ reg [8+3-1:0] pre_fifo_element_7;
+ reg [8+3-1:0] pre_fifo_element_8;
+ reg [8+3-1:0] pre_fifo_element_9;
+
+ always @( posedge Reset or posedge Clk )
+ if ( Reset )
+ begin
+ pre_fifo_element_0 <= 'b0;
+ pre_fifo_element_1 <= 'b0;
+ pre_fifo_element_2 <= 'b0;
+ pre_fifo_element_3 <= 'b0;
+ pre_fifo_element_4 <= 'b0;
+ pre_fifo_element_5 <= 'b0;
+ pre_fifo_element_6 <= 'b0;
+ pre_fifo_element_7 <= 'b0;
+ pre_fifo_element_8 <= 'b0;
+ pre_fifo_element_9 <= 'b0;
+ end
+ else
+ begin
+ if ( pre_fifo_data_drop )
+ begin
+ pre_fifo_element_0 <= 'b0;
+ pre_fifo_element_1 <= 'b0;
+ pre_fifo_element_2 <= 'b0;
+ pre_fifo_element_3 <= 'b0;
+ pre_fifo_element_4 <= 'b0;
+ pre_fifo_element_5 <= 'b0;
+ pre_fifo_element_6 <= 'b0;
+ pre_fifo_element_7 <= 'b0;
+ pre_fifo_element_8 <= 'b0;
+ pre_fifo_element_9 <= 'b0;
+ end
+ else
+ begin
+ pre_fifo_element_0 <= pre_fifo_element_1;
+ pre_fifo_element_1 <= pre_fifo_element_2;
+ pre_fifo_element_2 <= pre_fifo_element_3;
+ pre_fifo_element_3 <= pre_fifo_element_4;
+ pre_fifo_element_4 <= pre_fifo_element_5;
+ pre_fifo_element_5 <= pre_fifo_element_6;
+ pre_fifo_element_6 <= pre_fifo_element_7;
+ pre_fifo_element_7 <= pre_fifo_element_8;
+ pre_fifo_element_8 <= pre_fifo_element_9;
+ pre_fifo_element_9 <= { pre_fifo_data_en,
+ pre_fifo_data_err,
+ pre_fifo_data_end,
+ pre_fifo_wrdata };
+ end
+ end
+
+ assign Fifo_data = pre_fifo_element_0[7:0];
+ assign Fifo_data_end = pre_fifo_element_0[8];
+ assign Fifo_data_err = pre_fifo_element_0[9];
+ assign Fifo_data_en = pre_fifo_element_0[10];
+
+ assign CRC_data = pre_fifo_wrdata;
+ assign MAC_add_data = pre_fifo_wrdata;
+
+//******************************************************************************
+//State_machine
+//******************************************************************************
+
+always @( posedge Reset or posedge Clk )
+ if ( Reset )
+ Current_state <= State_idle;
+ else
+ Current_state <= Next_state;
+
+always @ (*)
+ case (Current_state)
+ State_idle:
+ if ( Crs_dv&&RxD==8'h55 )
+ Next_state = State_preamble;
+ else
+ Next_state = Current_state;
+
+ State_preamble:
+ if ( !Crs_dv )
+ Next_state = State_DropEnd;
+ else if ( RxErr )
+ Next_state = State_DropEnd;
+ else if ( RxD==8'hd5 )
+ Next_state = State_SFD;
+ else if ( RxD==8'h55 )
+ Next_state =Current_state;
+ else
+ Next_state = State_DropEnd;
+
+ State_SFD:
+ if ( !Crs_dv )
+ Next_state = State_DropEnd;
+ else if ( RxErr )
+ Next_state = State_DropEnd;
+ else
+ Next_state = State_data;
+
+ State_data:
+ if ( !Crs_dv && !ProcessingHeader && !Too_short && !Too_long )
+ Next_state = State_checkCRC;
+ else if ( !Crs_dv && ProcessingHeader )
+ Next_state = State_Drop2End;
+ else if ( !Crs_dv && (Too_short | Too_long) )
+ Next_state = State_ErrEnd;
+ else if ( Fifo_full )
+ Next_state = State_FFFullErrEnd;
+ else if ( RxErr && ProcessingHeader )
+ Next_state = State_Drop2End;
+ else if ( RxErr || Too_long )
+ Next_state = State_ErrEnd;
+ else if ( MAC_rx_add_chk_err || broadcast_drop )
+ Next_state = State_DropEnd;
+ else
+ Next_state = State_data;
+
+ State_checkCRC:
+ if ( CRC_err )
+ Next_state = State_CRCErrEnd;
+ else
+ Next_state = State_OkEnd;
+
+ State_OkEnd:
+ Next_state = State_IFG;
+
+ State_ErrEnd:
+ Next_state = State_IFG;
+
+ State_DropEnd:
+ Next_state = State_IFG;
+
+ State_Drop2End:
+ Next_state = State_IFG;
+
+ State_CRCErrEnd:
+ Next_state = State_IFG;
+
+ State_FFFullErrEnd:
+ Next_state = State_FFFullDrop;
+
+ State_FFFullDrop:
+ if ( !Crs_dv )
+ Next_state =State_IFG;
+ else
+ Next_state =Current_state;
+
+ State_IFG:
+ if ( IFG_counter==RX_IFG_SET-4 ) // Remove some additional time?
+ Next_state = State_idle;
+ else
+ Next_state = Current_state;
+
+ default:
+ Next_state = State_idle;
+ endcase
+
+always @( posedge Reset or posedge Clk )
+ if ( Reset )
+ IFG_counter <= 0;
+ else if ( Current_state!=State_IFG )
+ IFG_counter <= 0;
+ else
+ IFG_counter <= IFG_counter + 1;
+
+//******************************************************************************
+//gen fifo interface signals
+//******************************************************************************
+
+assign pre_fifo_wrdata = RxD_dl1;
+
+always @( Current_state )
+ if ( Current_state==State_data )
+ pre_fifo_data_en = 1;
+ else
+ pre_fifo_data_en = 0;
+
+always @( Current_state )
+ if ( (Current_state==State_ErrEnd ) ||
+ (Current_state==State_OkEnd ) ||
+ (Current_state==State_CRCErrEnd ) ||
+ (Current_state==State_FFFullErrEnd) ||
+ (Current_state==State_DropEnd ) ||
+ (Current_state==State_Drop2End ) )
+ pre_fifo_data_end = 1;
+ else
+ pre_fifo_data_end = 0;
+
+always @( Current_state )
+ if ( (Current_state==State_ErrEnd ) ||
+ (Current_state==State_CRCErrEnd ) ||
+ (Current_state==State_FFFullErrEnd) ||
+ (Current_state==State_DropEnd ) ||
+ (Current_state==State_Drop2End ) )
+ pre_fifo_data_err = 1;
+ else
+ pre_fifo_data_err = 0;
+
+always @( Current_state )
+ if ( (Current_state==State_DropEnd ) ||
+ (Current_state==State_Drop2End) )
+ pre_fifo_data_drop = 1;
+ else
+ pre_fifo_data_drop = 0;
+
+ // Drop in main Rx FIFO is no longer supported!
+ assign Fifo_data_drop = 0;
+
+//******************************************************************************
+//CRC_chk interface
+//******************************************************************************
+
+always @(Current_state)
+ if (Current_state==State_data)
+ CRC_en =1;
+ else
+ CRC_en =0;
+
+always @(Current_state)
+ if (Current_state==State_SFD)
+ CRC_init =1;
+ else
+ CRC_init =0;
+
+//******************************************************************************
+//gen rmon signals
+//******************************************************************************
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Frame_length_counter <=0;
+ else if (Current_state==State_SFD)
+ Frame_length_counter <=1;
+ else if (Current_state==State_data)
+ Frame_length_counter <=Frame_length_counter+ 1'b1;
+
+always @( Frame_length_counter )
+ if ( Frame_length_counter < 8 )
+ ProcessingHeader = 1;
+ else
+ ProcessingHeader = 0;
+
+always @ (Frame_length_counter or RX_MIN_LENGTH)
+ if (Frame_length_counter<RX_MIN_LENGTH)
+ Too_short =1;
+ else
+ Too_short =0;
+
+always @ (*)
+ if (Frame_length_counter>RX_MAX_LENGTH)
+ Too_long =1;
+ else
+ Too_long =0;
+
+assign Rx_pkt_length_rmon = Frame_length_counter-1'b1;
+
+reg [2:0] Rx_apply_rmon_reg;
+
+always @( posedge Clk or posedge Reset )
+ if ( Reset )
+ begin
+ Rx_apply_rmon <= 0;
+ Rx_apply_rmon_reg <= 'b0;
+ end
+ else
+ begin
+ if ( (Current_state==State_OkEnd ) ||
+ (Current_state==State_ErrEnd ) ||
+ (Current_state==State_CRCErrEnd ) ||
+ (Current_state==State_Drop2End ) ||
+ (Current_state==State_FFFullErrEnd) )
+ Rx_apply_rmon <= 1;
+ else
+ if ( Rx_apply_rmon_reg[2] )
+ Rx_apply_rmon <= 0;
+
+ Rx_apply_rmon_reg <= { Rx_apply_rmon_reg[1:0], Rx_apply_rmon };
+ end
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Rx_pkt_err_type_rmon <=0;
+ else if (Current_state==State_CRCErrEnd)
+ Rx_pkt_err_type_rmon <=3'b001 ;//
+ else if (Current_state==State_FFFullErrEnd)
+ Rx_pkt_err_type_rmon <=3'b010 ;//
+ else if ( (Current_state==State_ErrEnd) || (Current_state==State_Drop2End) )
+ Rx_pkt_err_type_rmon <=3'b011 ;//
+ else if(Current_state==State_OkEnd)
+ Rx_pkt_err_type_rmon <=3'b100 ;
+
+
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Rx_pkt_type_rmon <=0;
+ else if (Current_state==State_OkEnd&&pause_frame_ptr)
+ Rx_pkt_type_rmon <=3'b100 ;//
+ else if(Current_state==State_SFD&&Next_state==State_data)
+ Rx_pkt_type_rmon <={1'b0,MRxD[7:6]};
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ broadcast_ptr <=0;
+ else if(Current_state==State_IFG)
+ broadcast_ptr <=0;
+ else if(Current_state==State_SFD&&Next_state==State_data&&MRxD[7:6]==2'b11)
+ broadcast_ptr <=1;
+
+
+
+//******************************************************************************
+//MAC add checker signals
+//******************************************************************************
+always @ (Frame_length_counter or pre_fifo_data_en)
+ if(Frame_length_counter>=1&&Frame_length_counter<=6)
+ MAC_add_en <=pre_fifo_data_en;
+ else
+ MAC_add_en <=0;
+
+//******************************************************************************
+//flow control signals
+//******************************************************************************
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Pause_current <=Pause_idle;
+ else
+ Pause_current <=Pause_next;
+
+always @ (*)
+ case (Pause_current)
+ Pause_idle :
+ if(Current_state==State_SFD)
+ Pause_next =Pause_pre_syn;
+ else
+ Pause_next =Pause_current;
+ Pause_pre_syn:
+ case (Frame_length_counter)
+ 16'd1: if (RxD_dl1==8'h01)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd2: if (RxD_dl1==8'h80)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd3: if (RxD_dl1==8'hc2)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd4: if (RxD_dl1==8'h00)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd5: if (RxD_dl1==8'h00)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd6: if (RxD_dl1==8'h01)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd13: if (RxD_dl1==8'h88)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd14: if (RxD_dl1==8'h08)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd15: if (RxD_dl1==8'h00)
+ Pause_next =Pause_current;
+ else
+ Pause_next =Pause_idle;
+ 16'd16: if (RxD_dl1==8'h01)
+ Pause_next =Pause_quanta_hi;
+ else
+ Pause_next =Pause_idle;
+ default: Pause_next =Pause_current;
+ endcase
+ Pause_quanta_hi :
+ Pause_next =Pause_quanta_lo;
+ Pause_quanta_lo :
+ Pause_next =Pause_syn;
+ Pause_syn :
+ if (Current_state==State_IFG)
+ Pause_next =Pause_idle;
+ else
+ Pause_next =Pause_current;
+ default
+ Pause_next =Pause_idle;
+ endcase
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ pause_quanta_h <=0;
+ else if(Pause_current==Pause_quanta_hi)
+ pause_quanta_h <=RxD_dl1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ pause_quanta <=0;
+ else if(Pause_current==Pause_quanta_lo)
+ pause_quanta <={pause_quanta_h,RxD_dl1};
+
+ // The following 2 always blocks are a strange way of holding
+ // pause_quanta_val high for 2 cycles
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ pause_quanta_val_tmp <=0;
+ else if(Current_state==State_OkEnd&&Pause_current==Pause_syn)
+ pause_quanta_val_tmp <=1;
+ else
+ pause_quanta_val_tmp <=0;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ pause_quanta_val <=0;
+ else if(Current_state==State_OkEnd&&Pause_current==Pause_syn||pause_quanta_val_tmp)
+ pause_quanta_val <=1;
+ else
+ pause_quanta_val <=0;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ pause_frame_ptr <=0;
+ else if(Pause_current==Pause_syn)
+ pause_frame_ptr <=1;
+ else
+ pause_frame_ptr <=0;
+
+endmodule
+
+
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_top.v b/usrp2/fpga/eth/rtl/verilog/MAC_top.v new file mode 100644 index 000000000..d93b287ce --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_top.v @@ -0,0 +1,516 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// MAC_top.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module MAC_top
+ #(parameter TX_FF_DEPTH = 9,
+ parameter RX_FF_DEPTH = 9)
+ (
+ // System signals
+ input Clk_125M,
+ input Clk_user,
+
+ input rst_mac,
+ input rst_user,
+
+ // Wishbone compliant core host interface
+ input RST_I, // Active high (async) reset of the Wishbone interface
+ input CLK_I, // Wishbone interface clock (nominally 50 MHz)
+ input STB_I, // Active high module-select
+ input CYC_I, // Active high cycle-enable
+ input [6:0] ADR_I, // Module register address
+ input WE_I, // Active high for writes, low for reads
+ input [31:0] DAT_I, // Write data
+ output [31:0] DAT_O, // Read data
+ output ACK_O, // Acknowledge output – single high pulse
+
+ // User (packet) interface
+ output Rx_mac_empty,
+ input Rx_mac_rd,
+ output [31:0] Rx_mac_data,
+ output [1:0] Rx_mac_BE,
+ output Rx_mac_sop,
+ output Rx_mac_eop,
+ output Rx_mac_err,
+
+ output Tx_mac_wa,
+ input Tx_mac_wr,
+ input [31:0] Tx_mac_data,
+ input [1:0] Tx_mac_BE,
+ input Tx_mac_sop,
+ input Tx_mac_eop,
+
+ // PHY interface (GMII/MII)
+ output Gtx_clk, // Used only in GMII mode
+ input Rx_clk,
+ input Tx_clk, // Used only in MII mode
+ output Tx_er,
+ output Tx_en,
+ output [7:0] Txd,
+ input Rx_er,
+ input Rx_dv,
+ input [7:0] Rxd,
+ input Crs,
+ input Col,
+
+ // MDIO interface (to PHY)
+ inout Mdio,
+ output Mdc,
+
+ // FIFO levels
+ output [15:0] rx_fifo_occupied,
+ output rx_fifo_full,
+ output rx_fifo_empty,
+ output [15:0] tx_fifo_occupied,
+ output tx_fifo_full,
+ output tx_fifo_empty,
+
+ // Debug Interface
+ output [31:0] debug0,
+ output [31:0] debug1
+);
+
+ wire rst_mac_rx = rst_mac;
+ wire rst_mac_tx = rst_mac;
+ wire [2:0] Speed;
+
+ wire [31:0] debug_rx;
+ wire [31:0] debug_tx0;
+ wire [31:0] debug_tx1;
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ // RMON interface
+ wire [15:0] Rx_pkt_length_rmon;
+ wire Rx_apply_rmon;
+ wire [2:0] Rx_pkt_err_type_rmon;
+ wire [2:0] Rx_pkt_type_rmon;
+ wire [2:0] Tx_pkt_type_rmon;
+ wire [15:0] Tx_pkt_length_rmon;
+ wire Tx_apply_rmon;
+ wire [2:0] Tx_pkt_err_type_rmon;
+
+ // PHY interface
+ wire MCrs_dv;
+ wire [7:0] MRxD;
+ wire MRxErr;
+
+ // Flow-control signals
+ wire [15:0] pause_quanta;
+ wire pause_quanta_val;
+ wire [15:0] rx_fifo_space;
+ wire pause_apply, pause_quanta_sub;
+ wire xon_gen, xoff_gen, xon_gen_complete, xoff_gen_complete;
+ wire [15:0] fc_hwmark, fc_lwmark;
+
+ //PHY interface
+ wire [7:0] MTxD;
+ wire MTxEn;
+ wire MCRS;
+
+ // Interface clk signals
+ wire MAC_tx_clk;
+ wire MAC_rx_clk;
+ wire MAC_tx_clk_div;
+ wire MAC_rx_clk_div;
+
+ // Reg signals
+ wire [4:0] Tx_Hwmark;
+ wire [4:0] Tx_Lwmark;
+ wire pause_frame_send_en;
+ wire [15:0] pause_quanta_set;
+ wire MAC_tx_add_en;
+ wire FullDuplex;
+ wire [3:0] MaxRetry;
+ wire [5:0] IFGset;
+ wire [7:0] MAC_tx_add_prom_data;
+ wire [2:0] MAC_tx_add_prom_add;
+ wire MAC_tx_add_prom_wr;
+ wire tx_pause_en;
+
+ // Rx host interface
+ wire MAC_rx_add_chk_en;
+ wire [7:0] MAC_rx_add_prom_data;
+ wire [2:0] MAC_rx_add_prom_add;
+ wire MAC_rx_add_prom_wr;
+ wire broadcast_filter_en;
+ wire RX_APPEND_CRC;
+ wire [4:0] Rx_Hwmark;
+ wire [4:0] Rx_Lwmark;
+ wire CRC_chk_en;
+ wire [5:0] RX_IFG_SET;
+ wire [15:0] RX_MAX_LENGTH;
+ wire [6:0] RX_MIN_LENGTH;
+
+ // RMON host interface
+ wire [5:0] CPU_rd_addr;
+ wire CPU_rd_apply;
+ wire CPU_rd_grant;
+ wire [31:0] CPU_rd_dout;
+
+ // PHY int host interface
+ wire Line_loop_en;
+
+ // MII to CPU
+ wire [7:0] Divider;
+ wire [15:0] CtrlData;
+ wire [4:0] Rgad;
+ wire [4:0] Fiad;
+ wire NoPre;
+ wire WCtrlData;
+ wire RStat;
+ wire ScanStat;
+ wire Busy;
+ wire LinkFail;
+ wire Nvalid;
+ wire [15:0] Prsd;
+ wire WCtrlDataStart;
+ wire RStatStart;
+ wire UpdateMIIRX_DATAReg;
+ wire [15:0] broadcast_bucket_depth;
+ wire [15:0] broadcast_bucket_interval;
+
+ //-------------------------------------------------------------------------
+ // Instantiation of sub-modules
+ //-------------------------------------------------------------------------
+
+ MAC_rx #(.RX_FF_DEPTH(RX_FF_DEPTH))
+ U_MAC_rx(
+ .Reset ( rst_mac_rx ),
+ .Clk_user ( Clk_user ),
+ .Clk ( MAC_rx_clk_div ),
+
+ // RMII interface
+ .MCrs_dv ( MCrs_dv ),
+ .MRxD ( MRxD ),
+ .MRxErr ( MRxErr ),
+
+ // Flow-control signals
+ .pause_quanta ( pause_quanta ),
+ .pause_quanta_val ( pause_quanta_val ),
+ .rx_fifo_space ( rx_fifo_space ),
+
+ // User interface
+ .Rx_mac_empty ( Rx_mac_empty ),
+ .Rx_mac_rd ( Rx_mac_rd ),
+ .Rx_mac_data ( Rx_mac_data ),
+ .Rx_mac_BE ( Rx_mac_BE ),
+ .Rx_mac_sop ( Rx_mac_sop ),
+ .Rx_mac_eop ( Rx_mac_eop ),
+ .Rx_mac_err ( Rx_mac_err ),
+
+ // CPU
+ .MAC_rx_add_chk_en ( MAC_rx_add_chk_en ),
+ .MAC_add_prom_data ( MAC_rx_add_prom_data ),
+ .MAC_add_prom_add ( MAC_rx_add_prom_add ),
+ .MAC_add_prom_wr ( MAC_rx_add_prom_wr ),
+ .broadcast_filter_en ( broadcast_filter_en ),
+ .broadcast_bucket_depth ( broadcast_bucket_depth ),
+ .broadcast_bucket_interval( broadcast_bucket_interval ),
+ .RX_APPEND_CRC ( RX_APPEND_CRC ),
+ .Rx_Hwmark ( Rx_Hwmark ),
+ .Rx_Lwmark ( Rx_Lwmark ),
+ .CRC_chk_en ( CRC_chk_en ),
+ .RX_IFG_SET ( RX_IFG_SET ),
+ .RX_MAX_LENGTH ( RX_MAX_LENGTH ),
+ .RX_MIN_LENGTH ( RX_MIN_LENGTH ),
+
+ // RMON interface
+ .Rx_pkt_length_rmon ( Rx_pkt_length_rmon ),
+ .Rx_apply_rmon ( Rx_apply_rmon ),
+ .Rx_pkt_err_type_rmon ( Rx_pkt_err_type_rmon ),
+ .Rx_pkt_type_rmon ( Rx_pkt_type_rmon ),
+
+ .rx_fifo_occupied(rx_fifo_occupied),
+ .rx_fifo_full(rx_fifo_full),
+ .rx_fifo_empty(rx_fifo_empty),
+ .debug(debug_rx)
+ );
+
+ MAC_tx #(.TX_FF_DEPTH(TX_FF_DEPTH))
+ U_MAC_tx(
+ .Reset ( rst_mac_tx ),
+ .Clk ( MAC_tx_clk_div ),
+ //.Clk_user ( Clk_user ),
+ .Clk_user ( MAC_tx_clk_div ),
+
+ // PHY interface
+ .TxD ( MTxD ),
+ .TxEn ( MTxEn ),
+ .CRS ( MCRS ),
+
+ // RMON
+ .Tx_pkt_type_rmon ( Tx_pkt_type_rmon ),
+ .Tx_pkt_length_rmon ( Tx_pkt_length_rmon ),
+ .Tx_apply_rmon ( Tx_apply_rmon ),
+ .Tx_pkt_err_type_rmon( Tx_pkt_err_type_rmon ),
+
+ // User interface
+ .Tx_mac_wa ( Tx_mac_wa ),
+ .Tx_mac_wr ( Tx_mac_wr ),
+ .Tx_mac_data ( Tx_mac_data ),
+ .Tx_mac_BE ( Tx_mac_BE ),
+ .Tx_mac_sop ( Tx_mac_sop ),
+ .Tx_mac_eop ( Tx_mac_eop ),
+
+ // Host interface
+ .Tx_Hwmark ( Tx_Hwmark ),
+ .Tx_Lwmark ( Tx_Lwmark ),
+ .MAC_tx_add_en ( MAC_tx_add_en ),
+ .FullDuplex ( FullDuplex ),
+ .MaxRetry ( MaxRetry ),
+ .IFGset ( IFGset ),
+ .MAC_add_prom_data ( MAC_tx_add_prom_data ),
+ .MAC_add_prom_add ( MAC_tx_add_prom_add ),
+ .MAC_add_prom_wr ( MAC_tx_add_prom_wr ),
+
+ .pause_apply ( pause_apply ),
+ .pause_quanta_sub ( pause_quanta_sub ),
+ .pause_quanta_set ( pause_quanta_set ),
+ .xoff_gen ( xoff_gen ),
+ .xon_gen ( xon_gen ),
+ .xoff_gen_complete ( xoff_gen_complete ),
+ .xon_gen_complete ( xon_gen_complete ),
+ .debug0(debug_tx0),
+ .debug1(debug_tx1)
+ );
+
+ // Flow control outbound -- when other side sends PAUSE, we wait
+ flow_ctrl_tx flow_ctrl_tx
+ (.rst(rst_mac_tx),
+ .tx_clk(MAC_tx_clk_div),
+ // Setting
+ .tx_pause_en ( tx_pause_en ),
+ // From RX side
+ .pause_quanta (pause_quanta),
+ .pause_quanta_val(pause_quanta_val), // Other guy sent a PAUSE
+ // To TX side
+ .pause_apply (pause_apply), // To TX, stop sending new frames
+ .pause_quanta_sub (pause_quanta_sub) // From TX, indicates we have used up 1 quanta
+ );
+
+ flow_ctrl_rx flow_ctrl_rx // When we are running out of RX space, send a PAUSE
+ (.rst(rst_mac_rx), // FIXME
+ // Settings
+ .pause_frame_send_en ( pause_frame_send_en ),
+ .pause_quanta_set ( pause_quanta_set ),
+ .fc_hwmark (fc_hwmark),
+ .fc_lwmark (fc_lwmark),
+ // From RX side
+ .rx_clk(MAC_rx_clk_div),
+ .rx_fifo_space (rx_fifo_space), // Decide if we need to send a PAUSE
+ // To TX side
+ .tx_clk(MAC_tx_clk_div),
+ .xoff_gen (xoff_gen),
+ .xon_gen(xon_gen), // Tell our TX to send PAUSE frames
+ .xoff_gen_complete (xoff_gen_complete),
+ .xon_gen_complete(xon_gen_complete)
+ );
+
+ RMON U_RMON(
+ .Clk ( CLK_I ),
+ .Reset ( RST_I ),
+
+ // Tx RMON
+ .Tx_pkt_type_rmon ( Tx_pkt_type_rmon ),
+ .Tx_pkt_length_rmon ( Tx_pkt_length_rmon ),
+ .Tx_apply_rmon ( Tx_apply_rmon ),
+ .Tx_pkt_err_type_rmon( Tx_pkt_err_type_rmon ),
+
+ // Rx RMON
+ .Rx_pkt_type_rmon ( Rx_pkt_type_rmon ),
+ .Rx_pkt_length_rmon ( Rx_pkt_length_rmon ),
+ .Rx_apply_rmon ( Rx_apply_rmon ),
+ .Rx_pkt_err_type_rmon( Rx_pkt_err_type_rmon ),
+
+ // CPU
+ .CPU_rd_addr ( CPU_rd_addr ),
+ .CPU_rd_apply ( CPU_rd_apply ),
+ .CPU_rd_grant ( CPU_rd_grant ),
+ .CPU_rd_dout ( CPU_rd_dout )
+ );
+
+ Phy_int U_Phy_int(
+ .rst_mac_rx ( rst_mac_rx ),
+ .rst_mac_tx ( rst_mac_tx ),
+ .MAC_rx_clk ( MAC_rx_clk ),
+ .MAC_tx_clk ( MAC_tx_clk ),
+ // Rx interface
+ .MCrs_dv ( MCrs_dv ),
+ .MRxD ( MRxD ),
+ .MRxErr ( MRxErr ),
+ // Tx interface
+ .MTxD ( MTxD ),
+ .MTxEn ( MTxEn ),
+ .MCRS ( MCRS ),
+ // PHY interface
+ .Tx_er ( Tx_er ),
+ .Tx_en ( Tx_en ),
+ .Txd ( Txd ),
+ .Rx_er ( Rx_er ),
+ .Rx_dv ( Rx_dv ),
+ .Rxd ( Rxd ),
+ .Crs ( Crs ),
+ .Col ( Col ),
+ // Host interface
+ .Line_loop_en( Line_loop_en ),
+ .Speed ( Speed ) );
+
+ Clk_ctrl U_Clk_ctrl(
+ .Reset ( rst_mac ),
+ .Clk_125M ( Clk_125M ),
+
+ // Host interface
+ .Speed ( Speed ),
+
+ // Phy interface
+ .Gtx_clk ( Gtx_clk ),
+ .Rx_clk ( Rx_clk ),
+ .Tx_clk ( Tx_clk ),
+
+ // Interface clocks
+ .MAC_tx_clk ( MAC_tx_clk ),
+ .MAC_rx_clk ( MAC_rx_clk ),
+ .MAC_tx_clk_div( MAC_tx_clk_div ),
+ .MAC_rx_clk_div( MAC_rx_clk_div )
+ );
+
+ eth_miim U_eth_miim(
+ .Clk ( CLK_I ),
+ .Reset ( RST_I ),
+ .Divider ( Divider ),
+ .NoPre ( NoPre ),
+ .CtrlData ( CtrlData ),
+ .Rgad ( Rgad ),
+ .Fiad ( Fiad ),
+ .WCtrlData ( WCtrlData ),
+ .RStat ( RStat ),
+ .ScanStat ( ScanStat ),
+ .Mdio ( Mdio ),
+ .Mdc ( Mdc ),
+ .Busy ( Busy ),
+ .Prsd ( Prsd ),
+ .LinkFail ( LinkFail ),
+ .Nvalid ( Nvalid ),
+ .WCtrlDataStart ( WCtrlDataStart ),
+ .RStatStart ( RStatStart ),
+ .UpdateMIIRX_DATAReg( UpdateMIIRX_DATAReg )
+ );
+
+ Reg_int U_Reg_int(
+ // Wishbone compliant core host interface
+ .CLK_I( CLK_I ),
+ .RST_I( RST_I ),
+ .STB_I( STB_I ),
+ .CYC_I( CYC_I ),
+ .ADR_I( ADR_I ),
+ .WE_I ( WE_I ),
+ .DAT_I( DAT_I ),
+ .DAT_O( DAT_O ),
+ .ACK_O( ACK_O ),
+
+ // Tx host interface
+ .Tx_Hwmark ( Tx_Hwmark ),
+ .Tx_Lwmark ( Tx_Lwmark ),
+ .MAC_tx_add_en ( MAC_tx_add_en ),
+ .FullDuplex ( FullDuplex ),
+ .MaxRetry ( MaxRetry ),
+ .IFGset ( IFGset ),
+ .MAC_tx_add_prom_data ( MAC_tx_add_prom_data ),
+ .MAC_tx_add_prom_add ( MAC_tx_add_prom_add ),
+ .MAC_tx_add_prom_wr ( MAC_tx_add_prom_wr ),
+
+ // Rx host interface
+ .MAC_rx_add_chk_en ( MAC_rx_add_chk_en ),
+ .MAC_rx_add_prom_data ( MAC_rx_add_prom_data ),
+ .MAC_rx_add_prom_add ( MAC_rx_add_prom_add ),
+ .MAC_rx_add_prom_wr ( MAC_rx_add_prom_wr ),
+ .broadcast_filter_en ( broadcast_filter_en ),
+ .broadcast_bucket_depth ( broadcast_bucket_depth ),
+ .broadcast_bucket_interval( broadcast_bucket_interval ),
+ .RX_APPEND_CRC ( RX_APPEND_CRC ),
+ .Rx_Hwmark ( Rx_Hwmark ),
+ .Rx_Lwmark ( Rx_Lwmark ),
+ .CRC_chk_en ( CRC_chk_en ),
+ .RX_IFG_SET ( RX_IFG_SET ),
+ .RX_MAX_LENGTH ( RX_MAX_LENGTH ),
+ .RX_MIN_LENGTH ( RX_MIN_LENGTH ),
+
+ // Flow Control settings
+ .pause_frame_send_en ( pause_frame_send_en ),
+ .pause_quanta_set ( pause_quanta_set ),
+ .tx_pause_en ( tx_pause_en ),
+ .fc_hwmark ( fc_hwmark ),
+ .fc_lwmark ( fc_lwmark ),
+
+ // RMON host interface
+ .CPU_rd_addr ( CPU_rd_addr ),
+ .CPU_rd_apply ( CPU_rd_apply ),
+ .CPU_rd_grant ( CPU_rd_grant ),
+ .CPU_rd_dout ( CPU_rd_dout ),
+
+ // PHY int host interface
+ .Line_loop_en ( Line_loop_en ),
+ .Speed ( Speed ),
+
+ // MII to CPU
+ .Divider ( Divider ),
+ .CtrlData ( CtrlData ),
+ .Rgad ( Rgad ),
+ .Fiad ( Fiad ),
+ .NoPre ( NoPre ),
+ .WCtrlData ( WCtrlData ),
+ .RStat ( RStat ),
+ .ScanStat ( ScanStat ),
+ .Busy ( Busy ),
+ .LinkFail ( LinkFail ),
+ .Nvalid ( Nvalid ),
+ .Prsd ( Prsd ),
+ .WCtrlDataStart ( WCtrlDataStart ),
+ .RStatStart ( RStatStart ),
+ .UpdateMIIRX_DATAReg ( UpdateMIIRX_DATAReg )
+ );
+
+ assign debug0 = {xon_gen, xoff_gen, Tx_en, Rx_dv};
+ //assign debug0 = {{debug_rx[3:0], xon_gen, xon_gen_complete, xoff_gen, xoff_gen_complete},
+ // {1'b0,Rx_mac_err,Rx_mac_empty,Rx_mac_rd,Rx_mac_sop,Rx_mac_eop,Rx_mac_BE[1:0]},
+ // {rx_fifo_space}};
+ //assign debug0 = debug_tx0;
+ //assign debug1 = debug_tx1;
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_tx.v b/usrp2/fpga/eth/rtl/verilog/MAC_tx.v new file mode 100644 index 000000000..50b08dffb --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_tx.v @@ -0,0 +1,245 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// MAC_tx.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: MAC_tx.v,v $
+// Revision 1.4 2006/11/17 17:53:07 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:53 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:14 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+module MAC_tx
+ #(parameter TX_FF_DEPTH = 9)
+ (
+input Reset ,
+input Clk ,
+input Clk_user ,
+ //PHY interface
+output [7:0] TxD ,
+output TxEn ,
+input CRS ,
+ //RMON
+output [2:0] Tx_pkt_type_rmon ,
+output [15:0] Tx_pkt_length_rmon ,
+output Tx_apply_rmon ,
+output [2:0] Tx_pkt_err_type_rmon,
+ //user interface
+output Tx_mac_wa ,
+input Tx_mac_wr ,
+input [31:0] Tx_mac_data ,
+input [1:0] Tx_mac_BE ,//big endian
+input Tx_mac_sop ,
+input Tx_mac_eop ,
+ //host interface
+input [4:0] Tx_Hwmark ,
+input [4:0] Tx_Lwmark ,
+input MAC_tx_add_en ,
+input FullDuplex ,
+input [3:0] MaxRetry ,
+input [5:0] IFGset ,
+input [7:0] MAC_add_prom_data ,
+input [2:0] MAC_add_prom_add ,
+input MAC_add_prom_wr ,
+ // Flow control stuff
+input pause_apply ,
+output pause_quanta_sub,
+input [15:0] pause_quanta_set ,
+input xoff_gen,
+input xon_gen,
+output xoff_gen_complete,
+output xon_gen_complete,
+ output [31:0] debug0,
+ output [31:0] debug1
+);
+
+ // ******************************************************************************
+ // internal signals
+ // ******************************************************************************
+ //CRC_gen Interface
+wire CRC_init ;
+wire[7:0] Frame_data ;
+wire Data_en ;
+wire CRC_rd ;
+wire CRC_end ;
+wire[7:0] CRC_out ;
+ //Random_gen interface
+wire Random_init ;
+wire[3:0] RetryCnt ;
+wire Random_time_meet ;//levle hight indicate random time passed away
+ //flow control
+ //MAC_rx_FF
+wire[7:0] Fifo_data ;
+wire Fifo_rd ;
+wire Fifo_eop ;
+wire Fifo_da ;
+wire Fifo_rd_finish ;
+wire Fifo_rd_retry ;
+wire Fifo_ra ;
+wire Fifo_data_err_empty ;
+wire Fifo_data_err_full ;
+ //MAC_tx_addr_add
+wire MAC_tx_addr_init ;
+wire MAC_tx_addr_rd ;
+wire[7:0] MAC_tx_addr_data ;
+
+//******************************************************************************
+//instantiation
+//******************************************************************************
+MAC_tx_ctrl U_MAC_tx_ctrl(
+.Reset (Reset ),
+.Clk (Clk ),
+ //CRC_gen Interface (//CRC_gen Interface ),
+.CRC_init (CRC_init ),
+.Frame_data (Frame_data ),
+.Data_en (Data_en ),
+.CRC_rd (CRC_rd ),
+.CRC_end (CRC_end ),
+.CRC_out (CRC_out ),
+ //Random_gen interfac (//Random_gen interfac ),
+.Random_init (Random_init ),
+.RetryCnt (RetryCnt ),
+.Random_time_meet (Random_time_meet ),
+ //flow control (//flow control ),
+.pause_apply (pause_apply ),
+.pause_quanta_sub (pause_quanta_sub ),
+.xoff_gen (xoff_gen ),
+.xoff_gen_complete (xoff_gen_complete ),
+.xon_gen (xon_gen ),
+.xon_gen_complete (xon_gen_complete ),
+ //MAC_tx_FF (//MAC_tx_FF ),
+.Fifo_data (Fifo_data ),
+.Fifo_rd (Fifo_rd ),
+.Fifo_eop (Fifo_eop ),
+.Fifo_da (Fifo_da ),
+.Fifo_rd_finish (Fifo_rd_finish ),
+.Fifo_rd_retry (Fifo_rd_retry ),
+.Fifo_ra (Fifo_ra ),
+.Fifo_data_err_empty (Fifo_data_err_empty ),
+.Fifo_data_err_full (Fifo_data_err_full ),
+ //RMII (//RMII ),
+.TxD (TxD ),
+.TxEn (TxEn ),
+.CRS (CRS ),
+ //MAC_tx_addr_add (//MAC_tx_addr_add ),
+.MAC_tx_addr_rd (MAC_tx_addr_rd ),
+.MAC_tx_addr_data (MAC_tx_addr_data ),
+.MAC_tx_addr_init (MAC_tx_addr_init ),
+ //RMON (//RMON ),
+.Tx_pkt_type_rmon (Tx_pkt_type_rmon ),
+.Tx_pkt_length_rmon (Tx_pkt_length_rmon ),
+.Tx_apply_rmon (Tx_apply_rmon ),
+.Tx_pkt_err_type_rmon (Tx_pkt_err_type_rmon ),
+ //CPU (//CPU ),
+.pause_quanta_set (pause_quanta_set ),
+.MAC_tx_add_en (MAC_tx_add_en ),
+.FullDuplex (FullDuplex ),
+.MaxRetry (MaxRetry ),
+.IFGset (IFGset )
+);
+
+CRC_gen U_CRC_gen(
+.Reset (Reset ),
+.Clk (Clk ),
+.Init (CRC_init ),
+.Frame_data (Frame_data ),
+.Data_en (Data_en ),
+.CRC_rd (CRC_rd ),
+.CRC_out (CRC_out ),
+.CRC_end (CRC_end )
+);
+
+ MAC_tx_addr_add U_MAC_tx_addr_add
+ (.Reset (Reset ),
+ .Clk (Clk ),
+ .MAC_tx_addr_rd (MAC_tx_addr_rd ),
+ .MAC_tx_addr_init (MAC_tx_addr_init ),
+ .MAC_tx_addr_data (MAC_tx_addr_data ),
+ //CPU
+ .MAC_add_prom_data (MAC_add_prom_data ),
+ .MAC_add_prom_add (MAC_add_prom_add ),
+ .MAC_add_prom_wr (MAC_add_prom_wr )
+ );
+
+MAC_tx_FF #(.TX_FF_DEPTH(TX_FF_DEPTH)) U_MAC_tx_FF(
+.Reset (Reset ),
+.Clk_MAC (Clk ),
+.Clk_SYS (Clk_user ),
+ //MAC_rx_ctrl interf (//MAC_rx_ctrl interf ),
+.Fifo_data (Fifo_data ),
+.Fifo_rd (Fifo_rd ),
+.Fifo_rd_finish (Fifo_rd_finish ),
+.Fifo_rd_retry (Fifo_rd_retry ),
+.Fifo_eop (Fifo_eop ),
+.Fifo_da (Fifo_da ),
+.Fifo_ra (Fifo_ra ),
+.Fifo_data_err_empty (Fifo_data_err_empty ),
+.Fifo_data_err_full (Fifo_data_err_full ),
+ //user interface (//user interface ),
+.Tx_mac_wa (Tx_mac_wa ),
+.Tx_mac_wr (Tx_mac_wr ),
+.Tx_mac_data (Tx_mac_data ),
+.Tx_mac_BE (Tx_mac_BE ),
+.Tx_mac_sop (Tx_mac_sop ),
+.Tx_mac_eop (Tx_mac_eop ),
+ //host interface (//host interface ),
+.FullDuplex (FullDuplex ),
+.Tx_Hwmark (Tx_Hwmark ),
+.Tx_Lwmark (Tx_Lwmark ),
+.debug0(debug0),
+.debug1(debug1)
+);
+
+Random_gen U_Random_gen(
+.Reset (Reset ),
+.Clk (Clk ),
+.Init (Random_init ),
+.RetryCnt (RetryCnt ),
+.Random_time_meet (Random_time_meet )
+);
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_tx/CRC_gen.v b/usrp2/fpga/eth/rtl/verilog/MAC_tx/CRC_gen.v new file mode 100644 index 000000000..4a16e7c36 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_tx/CRC_gen.v @@ -0,0 +1,169 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// CRC_gen.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: CRC_gen.v,v $
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:17 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module CRC_gen (
+Reset ,
+Clk ,
+Init ,
+Frame_data ,
+Data_en ,
+CRC_rd ,
+CRC_end ,
+CRC_out
+
+);
+input Reset ;
+input Clk ;
+input Init ;
+input [7:0] Frame_data ;
+input Data_en ;
+input CRC_rd ;
+output [7:0] CRC_out ;
+output CRC_end ;
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+reg [7:0] CRC_out ;
+reg [31:0] CRC_reg;
+reg CRC_end;
+reg [3:0] Counter;
+//******************************************************************************
+//******************************************************************************
+//input data width is 8bit, and the first bit is bit[0]
+function[31:0] NextCRC;
+ input[7:0] D;
+ input[31:0] C;
+ reg[31:0] NewCRC;
+ begin
+ NewCRC[0]=C[24]^C[30]^D[1]^D[7];
+ NewCRC[1]=C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[2]=C[26]^D[5]^C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[3]=C[27]^D[4]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[4]=C[28]^D[3]^C[27]^D[4]^C[26]^D[5]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[5]=C[29]^D[2]^C[28]^D[3]^C[27]^D[4]^C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[6]=C[30]^D[1]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[7]=C[31]^D[0]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[24]^D[7];
+ NewCRC[8]=C[0]^C[28]^D[3]^C[27]^D[4]^C[25]^D[6]^C[24]^D[7];
+ NewCRC[9]=C[1]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^D[6];
+ NewCRC[10]=C[2]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[24]^D[7];
+ NewCRC[11]=C[3]^C[28]^D[3]^C[27]^D[4]^C[25]^D[6]^C[24]^D[7];
+ NewCRC[12]=C[4]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[13]=C[5]^C[30]^D[1]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[14]=C[6]^C[31]^D[0]^C[30]^D[1]^C[28]^D[3]^C[27]^D[4]^C[26]^D[5];
+ NewCRC[15]=C[7]^C[31]^D[0]^C[29]^D[2]^C[28]^D[3]^C[27]^D[4];
+ NewCRC[16]=C[8]^C[29]^D[2]^C[28]^D[3]^C[24]^D[7];
+ NewCRC[17]=C[9]^C[30]^D[1]^C[29]^D[2]^C[25]^D[6];
+ NewCRC[18]=C[10]^C[31]^D[0]^C[30]^D[1]^C[26]^D[5];
+ NewCRC[19]=C[11]^C[31]^D[0]^C[27]^D[4];
+ NewCRC[20]=C[12]^C[28]^D[3];
+ NewCRC[21]=C[13]^C[29]^D[2];
+ NewCRC[22]=C[14]^C[24]^D[7];
+ NewCRC[23]=C[15]^C[25]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[24]=C[16]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[25]=C[17]^C[27]^D[4]^C[26]^D[5];
+ NewCRC[26]=C[18]^C[28]^D[3]^C[27]^D[4]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[27]=C[19]^C[29]^D[2]^C[28]^D[3]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[28]=C[20]^C[30]^D[1]^C[29]^D[2]^C[26]^D[5];
+ NewCRC[29]=C[21]^C[31]^D[0]^C[30]^D[1]^C[27]^D[4];
+ NewCRC[30]=C[22]^C[31]^D[0]^C[28]^D[3];
+ NewCRC[31]=C[23]^C[29]^D[2];
+ NextCRC=NewCRC;
+ end
+ endfunction
+//******************************************************************************
+
+always @ (posedge Clk) // or posedge Reset)
+// if (Reset)
+// CRC_reg <=32'hffffffff;
+// else
+ if (Init)
+ CRC_reg <=32'hffffffff;
+ else if (Data_en)
+ CRC_reg <=NextCRC(Frame_data,CRC_reg);
+ else if (CRC_rd)
+ CRC_reg <={CRC_reg[23:0],8'hff};
+
+always @ (CRC_rd or CRC_reg)
+// if (CRC_rd)
+ CRC_out <=~{
+ CRC_reg[24],
+ CRC_reg[25],
+ CRC_reg[26],
+ CRC_reg[27],
+ CRC_reg[28],
+ CRC_reg[29],
+ CRC_reg[30],
+ CRC_reg[31]
+ };
+// else
+// CRC_out <=0;
+
+//caculate CRC out length ,4 cycles
+//CRC_end aligned to last CRC checksum data
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ Counter <=0;
+ else if (!CRC_rd)
+ Counter <=0;
+ else
+ Counter <=Counter + 1;
+
+always @ (Counter)
+ if (Counter==3)
+ CRC_end=1;
+ else
+ CRC_end=0;
+
+endmodule
+
+
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_FF.v b/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_FF.v new file mode 100644 index 000000000..e62346fb7 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_FF.v @@ -0,0 +1,722 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// MAC_tx_FF.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module MAC_tx_FF
+ #(parameter TX_FF_DEPTH = 9)
+ (input Reset ,
+ input Clk_MAC ,
+ input Clk_SYS ,
+ //MAC_tx_ctrl
+ output reg [7:0]Fifo_data ,
+ input Fifo_rd ,
+ input Fifo_rd_finish ,
+ input Fifo_rd_retry ,
+ output reg Fifo_eop ,
+ output reg Fifo_da ,
+ output reg Fifo_ra ,
+ output reg Fifo_data_err_empty ,
+ output Fifo_data_err_full ,
+ //user interface
+ output reg Tx_mac_wa ,
+ input Tx_mac_wr ,
+ input [31:0] Tx_mac_data ,
+ input [1:0] Tx_mac_BE ,//big endian
+ input Tx_mac_sop ,
+ input Tx_mac_eop ,
+ //host interface
+ input FullDuplex ,
+ input [4:0] Tx_Hwmark ,
+ input [4:0] Tx_Lwmark ,
+ output [31:0] debug0,
+ output [31:0] debug1
+ );
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+localparam MAC_byte3 =4'd00;
+localparam MAC_byte2 =4'd01;
+localparam MAC_byte1 =4'd02;
+localparam MAC_byte0 =4'd03;
+localparam MAC_wait_finish =4'd04;
+localparam MAC_retry =4'd08;
+localparam MAC_idle =4'd09;
+localparam MAC_FFEmpty =4'd10;
+localparam MAC_FFEmpty_drop =4'd11;
+localparam MAC_pkt_sub =4'd12;
+localparam MAC_FF_Err =4'd13;
+
+
+reg [3:0] Next_state_MAC ;
+
+
+localparam SYS_idle =4'd0;
+localparam SYS_WaitSop =4'd1;
+localparam SYS_SOP =4'd2;
+localparam SYS_MOP =4'd3;
+localparam SYS_DROP =4'd4;
+localparam SYS_EOP_ok =4'd5;
+localparam SYS_FFEmpty =4'd6;
+localparam SYS_EOP_err =4'd7;
+localparam SYS_SOP_err =4'd8;
+
+reg [3:0] Next_state_SYS;
+
+reg [TX_FF_DEPTH-1:0] Add_wr ;
+reg [TX_FF_DEPTH-1:0] Add_wr_ungray ;
+reg [TX_FF_DEPTH-1:0] Add_wr_gray ;
+reg [TX_FF_DEPTH-1:0] Add_wr_gray_dl1 ;
+reg [TX_FF_DEPTH-1:0] Add_wr_gray_dl2 ;
+
+reg [TX_FF_DEPTH-1:0] Add_rd ;
+reg [TX_FF_DEPTH-1:0] Add_rd_reg ;
+reg [TX_FF_DEPTH-1:0] Add_rd_gray ;
+reg [TX_FF_DEPTH-1:0] Add_rd_gray_dl1 ;
+reg [TX_FF_DEPTH-1:0] Add_rd_gray_dl2 ;
+reg [TX_FF_DEPTH-1:0] Add_rd_ungray ;
+wire[35:0] Din ;
+wire[35:0] Dout ;
+reg Wr_en ;
+wire[TX_FF_DEPTH-1:0] Add_wr_pluse;
+wire[TX_FF_DEPTH-1:0] Add_wr_pluse_pluse;
+reg [TX_FF_DEPTH-1:TX_FF_DEPTH-5] Add_rd_reg_dl1;
+
+reg [3:0] Current_state_MAC;
+reg [3:0] Current_state_MAC_reg;
+reg [3:0] Current_state_SYS;
+reg Full;
+reg AlmostFull;
+reg Empty;
+reg [35:0] Dout_reg;
+reg Packet_number_sub_edge;
+reg Packet_number_add;
+reg [5:0] Packet_number_inFF;
+reg [5:0] Packet_number_inFF_reg;
+reg Dout_reg_en;
+reg Add_rd_add;
+
+
+reg Tx_mac_wr_dl1 ;
+reg [31:0] Tx_mac_data_dl1 ;
+reg [1:0] Tx_mac_BE_dl1 ;
+reg FF_FullErr ;
+wire[1:0] Dout_BE ;
+wire Dout_eop ;
+wire Dout_err ;
+wire[31:0] Dout_data ;
+reg Packet_number_sub_dl1 ;
+reg Packet_number_sub_dl2 ;
+reg [4:0] Fifo_data_count ;
+reg Fifo_ra_tmp ;
+reg Pkt_sub_apply_tmp ;
+reg Pkt_sub_apply ;
+reg Add_rd_reg_rdy_tmp ;
+reg Add_rd_reg_rdy ;
+reg Add_rd_reg_rdy_dl1 ;
+reg Add_rd_reg_rdy_dl2 ;
+reg [4:0] Tx_Hwmark_pl ;
+reg [4:0] Tx_Lwmark_pl ;
+reg Add_rd_jump_tmp ;
+reg Add_rd_jump_tmp_pl1 ;
+reg Add_rd_jump ;
+reg Add_rd_jump_wr_pl1 ;
+
+//******************************************************************************
+//write data to from FF .
+//domain Clk_SYS
+//******************************************************************************
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Current_state_SYS <=SYS_idle;
+ else
+ Current_state_SYS <=Next_state_SYS;
+
+always @ (Current_state_SYS or Tx_mac_wr or Tx_mac_sop or Full or AlmostFull
+ or Tx_mac_eop )
+ case (Current_state_SYS)
+ SYS_idle:
+ if (Tx_mac_wr&&Tx_mac_sop&&!Full)
+ Next_state_SYS =SYS_SOP;
+ else
+ Next_state_SYS =Current_state_SYS ;
+ SYS_SOP:
+ Next_state_SYS =SYS_MOP;
+ SYS_MOP:
+ if (AlmostFull)
+ Next_state_SYS =SYS_DROP;
+ else if (Tx_mac_wr&&Tx_mac_sop)
+ Next_state_SYS =SYS_SOP_err;
+ else if (Tx_mac_wr&&Tx_mac_eop)
+ Next_state_SYS =SYS_EOP_ok;
+ else
+ Next_state_SYS =Current_state_SYS ;
+ SYS_EOP_ok:
+ if (Tx_mac_wr&&Tx_mac_sop)
+ Next_state_SYS =SYS_SOP;
+ else
+ Next_state_SYS =SYS_idle;
+ SYS_EOP_err:
+ if (Tx_mac_wr&&Tx_mac_sop)
+ Next_state_SYS =SYS_SOP;
+ else
+ Next_state_SYS =SYS_idle;
+ SYS_SOP_err:
+ Next_state_SYS =SYS_DROP;
+ SYS_DROP: //FIFO overflow
+ if (Tx_mac_wr&&Tx_mac_eop)
+ Next_state_SYS =SYS_EOP_err;
+ else
+ Next_state_SYS =Current_state_SYS ;
+ default:
+ Next_state_SYS =SYS_idle;
+ endcase
+
+//delay signals
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Tx_mac_wr_dl1 <=0;
+ Tx_mac_data_dl1 <=0;
+ Tx_mac_BE_dl1 <=0;
+ end
+ else
+ begin
+ Tx_mac_wr_dl1 <=Tx_mac_wr ;
+ Tx_mac_data_dl1 <=Tx_mac_data ;
+ Tx_mac_BE_dl1 <=Tx_mac_BE ;
+ end
+
+always @(Current_state_SYS)
+ if (Current_state_SYS==SYS_EOP_err)
+ FF_FullErr =1;
+ else
+ FF_FullErr =0;
+
+reg Tx_mac_eop_gen;
+
+always @(Current_state_SYS)
+ if (Current_state_SYS==SYS_EOP_err||Current_state_SYS==SYS_EOP_ok)
+ Tx_mac_eop_gen =1;
+ else
+ Tx_mac_eop_gen =0;
+
+assign Din={Tx_mac_eop_gen,FF_FullErr,Tx_mac_BE_dl1,Tx_mac_data_dl1};
+
+always @(Current_state_SYS or Tx_mac_wr_dl1)
+ if ((Current_state_SYS==SYS_SOP||Current_state_SYS==SYS_EOP_ok||
+ Current_state_SYS==SYS_MOP||Current_state_SYS==SYS_EOP_err)&&Tx_mac_wr_dl1)
+ Wr_en = 1;
+ else
+ Wr_en = 0;
+
+
+//
+
+
+always @ (posedge Reset or posedge Clk_SYS)
+ if (Reset)
+ Add_wr_gray <=0;
+ else
+ begin : Add_wr_gray_loop
+ integer i;
+ Add_wr_gray[TX_FF_DEPTH-1] <=Add_wr[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_wr_gray[i] <=Add_wr[i+1]^Add_wr[i];
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_gray_dl1 <=0;
+ else
+ Add_rd_gray_dl1 <=Add_rd_gray;
+
+ always @(posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_gray_dl2 <= 0;
+ else
+ Add_rd_gray_dl2 <= Add_rd_gray_dl1;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_jump_wr_pl1 <=0;
+ else
+ Add_rd_jump_wr_pl1 <=Add_rd_jump;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_ungray =0;
+ else if (!Add_rd_jump_wr_pl1)
+ begin : Add_rd_ungray_loop
+ integer i;
+ Add_rd_ungray[TX_FF_DEPTH-1] = Add_rd_gray_dl2[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_rd_ungray[i] = Add_rd_ungray[i+1]^Add_rd_gray_dl2[i];
+ end
+
+assign Add_wr_pluse =Add_wr+1;
+assign Add_wr_pluse_pluse =Add_wr+4;
+
+always @ (Add_wr_pluse or Add_rd_ungray)
+ if (Add_wr_pluse==Add_rd_ungray)
+ Full =1;
+ else
+ Full =0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ AlmostFull <=0;
+ else if (Add_wr_pluse_pluse==Add_rd_ungray)
+ AlmostFull <=1;
+ else
+ AlmostFull <=0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_wr <= 0;
+ else if (Wr_en&&!Full)
+ Add_wr <= Add_wr +1;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Packet_number_sub_dl1 <=0;
+ Packet_number_sub_dl2 <=0;
+ end
+ else
+ begin
+ Packet_number_sub_dl1 <=Pkt_sub_apply;
+ Packet_number_sub_dl2 <=Packet_number_sub_dl1;
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_sub_edge <=0;
+ else if (Packet_number_sub_dl1&!Packet_number_sub_dl2)
+ Packet_number_sub_edge <=1;
+ else
+ Packet_number_sub_edge <=0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_add <=0;
+ else if (Current_state_SYS==SYS_EOP_ok||Current_state_SYS==SYS_EOP_err)
+ Packet_number_add <=1;
+ else
+ Packet_number_add <=0;
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_inFF <=0;
+ else if (Packet_number_add&&!Packet_number_sub_edge)
+ Packet_number_inFF <=Packet_number_inFF + 1'b1;
+ else if (!Packet_number_add&&Packet_number_sub_edge)
+ Packet_number_inFF <=Packet_number_inFF - 1'b1;
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_inFF_reg <=0;
+ else
+ Packet_number_inFF_reg <=Packet_number_inFF;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Add_rd_reg_rdy_dl1 <=0;
+ Add_rd_reg_rdy_dl2 <=0;
+ end
+ else
+ begin
+ Add_rd_reg_rdy_dl1 <=Add_rd_reg_rdy;
+ Add_rd_reg_rdy_dl2 <=Add_rd_reg_rdy_dl1;
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_reg_dl1 <=0;
+ else if (Add_rd_reg_rdy_dl1&!Add_rd_reg_rdy_dl2)
+ Add_rd_reg_dl1 <=Add_rd_reg[TX_FF_DEPTH-1:TX_FF_DEPTH-5];
+
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Fifo_data_count <=0;
+ else if (FullDuplex)
+ Fifo_data_count <=Add_wr[TX_FF_DEPTH-1:TX_FF_DEPTH-5]-Add_rd_ungray[TX_FF_DEPTH-1:TX_FF_DEPTH-5];
+ else
+ Fifo_data_count <=Add_wr[TX_FF_DEPTH-1:TX_FF_DEPTH-5]-Add_rd_reg_dl1[TX_FF_DEPTH-1:TX_FF_DEPTH-5]; //for half duplex backoff requirement
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Fifo_ra_tmp <=0;
+ else if (Packet_number_inFF_reg>=1||Fifo_data_count>=Tx_Lwmark)
+ Fifo_ra_tmp <=1;
+ else
+ Fifo_ra_tmp <=0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Tx_Hwmark_pl <=0;
+ Tx_Lwmark_pl <=0;
+ end
+ else
+ begin
+ Tx_Hwmark_pl <=Tx_Hwmark;
+ Tx_Lwmark_pl <=Tx_Lwmark;
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Tx_mac_wa <=0;
+ else if (Fifo_data_count>=Tx_Hwmark_pl)
+ Tx_mac_wa <=0;
+ else if (Fifo_data_count<Tx_Lwmark_pl)
+ Tx_mac_wa <=1;
+
+//******************************************************************************
+//rd data to from FF .
+//domain Clk_MAC
+//******************************************************************************
+reg[35:0] Dout_dl1;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Dout_dl1 <=0;
+ else
+ Dout_dl1 <=Dout;
+
+always @ (Current_state_MAC or Next_state_MAC)
+ if ((Current_state_MAC==MAC_idle||Current_state_MAC==MAC_byte0)&&Next_state_MAC==MAC_byte3)
+ Dout_reg_en =1;
+ else
+ Dout_reg_en =0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Dout_reg <=0;
+ else if (Dout_reg_en)
+ Dout_reg <=Dout_dl1;
+
+assign {Dout_eop,Dout_err,Dout_BE,Dout_data}=Dout_reg;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Current_state_MAC <=MAC_idle;
+ else
+ Current_state_MAC <=Next_state_MAC;
+
+always @ (Current_state_MAC or Fifo_rd or Dout_BE or Dout_eop or Fifo_rd_retry
+ or Fifo_rd_finish or Empty or Fifo_rd or Fifo_eop)
+ case (Current_state_MAC)
+ MAC_idle:
+ if (Empty&&Fifo_rd)
+ Next_state_MAC=MAC_FF_Err;
+ else if (Fifo_rd)
+ Next_state_MAC=MAC_byte3;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte3:
+ if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte2;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte2:
+ if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte1;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte1:
+ if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte0;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte0:
+ if (Empty&&Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_FFEmpty;
+ else if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte3;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_retry:
+ Next_state_MAC=MAC_idle;
+ MAC_wait_finish:
+ if (Fifo_rd_finish)
+ Next_state_MAC=MAC_pkt_sub;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_pkt_sub:
+ Next_state_MAC=MAC_idle;
+ MAC_FFEmpty:
+ if (!Empty)
+ Next_state_MAC=MAC_byte3;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_FF_Err: //stopped state-machine need change
+ Next_state_MAC=Current_state_MAC;
+ default
+ Next_state_MAC=MAC_idle;
+ endcase
+//
+always @ (posedge Reset or posedge Clk_MAC)
+ if (Reset)
+ Add_rd_gray <=0;
+ else
+ begin : Add_rd_gray_loop
+ integer i;
+ Add_rd_gray[TX_FF_DEPTH-1] <=Add_rd[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_rd_gray[i] <= Add_rd[i+1]^Add_rd[i];
+ end
+//
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_wr_gray_dl1 <=0;
+ else
+ Add_wr_gray_dl1 <=Add_wr_gray;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_wr_gray_dl2 <=0;
+ else
+ Add_wr_gray_dl2 <=Add_wr_gray_dl1;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_wr_ungray =0;
+ else
+ begin : Add_wr_ungray_loop
+ integer i;
+ Add_wr_ungray[TX_FF_DEPTH-1] = Add_wr_gray_dl2[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_wr_ungray[i] = Add_wr_ungray[i+1]^Add_wr_gray_dl2[i];
+ end
+
+//empty
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Empty <=1;
+ else if (Add_rd==Add_wr_ungray)
+ Empty <=1;
+ else
+ Empty <=0;
+
+//ra
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Fifo_ra <=0;
+ else
+ Fifo_ra <=Fifo_ra_tmp;
+
+
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Pkt_sub_apply_tmp <=0;
+ else if (Current_state_MAC==MAC_pkt_sub)
+ Pkt_sub_apply_tmp <=1;
+ else
+ Pkt_sub_apply_tmp <=0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Pkt_sub_apply <=0;
+ else if ((Current_state_MAC==MAC_pkt_sub)||Pkt_sub_apply_tmp)
+ Pkt_sub_apply <=1;
+ else
+ Pkt_sub_apply <=0;
+
+//reg Add_rd for collison retry
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_reg <=0;
+ else if (Fifo_rd_finish)
+ Add_rd_reg <=Add_rd;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_reg_rdy_tmp <=0;
+ else if (Fifo_rd_finish)
+ Add_rd_reg_rdy_tmp <=1;
+ else
+ Add_rd_reg_rdy_tmp <=0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_reg_rdy <=0;
+ else if (Fifo_rd_finish||Add_rd_reg_rdy_tmp)
+ Add_rd_reg_rdy <=1;
+ else
+ Add_rd_reg_rdy <=0;
+
+
+always @ (Current_state_MAC or Next_state_MAC)
+ if ((Current_state_MAC==MAC_idle||Current_state_MAC==MAC_byte0)&&Next_state_MAC==MAC_byte3)
+ Add_rd_add =1;
+ else
+ Add_rd_add =0;
+
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd <=0;
+ else if (Current_state_MAC==MAC_retry)
+ Add_rd <= Add_rd_reg;
+ else if (Add_rd_add)
+ Add_rd <= Add_rd + 1;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_jump_tmp <=0;
+ else if (Current_state_MAC==MAC_retry)
+ Add_rd_jump_tmp <=1;
+ else
+ Add_rd_jump_tmp <=0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_jump_tmp_pl1 <=0;
+ else
+ Add_rd_jump_tmp_pl1 <=Add_rd_jump_tmp;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_jump <=0;
+ else if (Current_state_MAC==MAC_retry)
+ Add_rd_jump <=1;
+ else if (Add_rd_jump_tmp_pl1)
+ Add_rd_jump <=0;
+
+//gen Fifo_data
+
+
+always @ (Dout_data or Current_state_MAC)
+ case (Current_state_MAC)
+ MAC_byte3:
+ Fifo_data =Dout_data[31:24];
+ MAC_byte2:
+ Fifo_data =Dout_data[23:16];
+ MAC_byte1:
+ Fifo_data =Dout_data[15:8];
+ MAC_byte0:
+ Fifo_data =Dout_data[7:0];
+ default:
+ Fifo_data =0;
+ endcase
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Fifo_da <=0;
+ else if ((Current_state_MAC==MAC_byte0||Current_state_MAC==MAC_byte1||
+ Current_state_MAC==MAC_byte2||Current_state_MAC==MAC_byte3)&&Fifo_rd&&!Fifo_eop)
+ Fifo_da <=1;
+ else
+ Fifo_da <=0;
+
+//gen Fifo_data_err_empty
+assign Fifo_data_err_full=Dout_err;
+//gen Fifo_data_err_empty
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Current_state_MAC_reg <=0;
+ else
+ Current_state_MAC_reg <=Current_state_MAC;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Fifo_data_err_empty <=0;
+ else if (Current_state_MAC_reg==MAC_FFEmpty)
+ Fifo_data_err_empty <=1;
+ else
+ Fifo_data_err_empty <=0;
+
+//always @ (posedge Clk_MAC)
+// if (Current_state_MAC_reg==MAC_FF_Err)
+// begin
+// $finish(2);
+// $display("mac_tx_FF meet error status at time :%t",$time);
+// end
+
+//gen Fifo_eop aligned to last valid data byte
+always @ ( Current_state_MAC or Dout_eop or Dout_BE )
+ if ( ( ( Current_state_MAC==MAC_byte0 && Dout_BE==2'b00 ) ||
+ ( Current_state_MAC==MAC_byte1 && Dout_BE==2'b11 ) ||
+ ( Current_state_MAC==MAC_byte2 && Dout_BE==2'b10 ) ||
+ ( Current_state_MAC==MAC_byte3 && Dout_BE==2'b01 ) ) && Dout_eop )
+ Fifo_eop = 1;
+ else
+ Fifo_eop = 0;
+
+ // Dual port RAM for FIFO
+ ram_2port #(.DWIDTH(36),.AWIDTH(TX_FF_DEPTH)) mac_tx_ff_ram
+ (.clka(Clk_SYS),.ena(1'b1),.wea(Wr_en),.addra(Add_wr),.dia(Din),.doa(),
+ .clkb(Clk_MAC),.enb(1'b1),.web(1'b0),.addrb(Add_rd),.dib(36'b0),.dob(Dout) );
+
+ assign debug0 =
+ { { 5'd0, Empty, Full, AlmostFull },
+ { Current_state_SYS, Current_state_MAC },
+ { Fifo_rd, Fifo_rd_finish, Fifo_rd_retry, Fifo_eop, Fifo_da, Fifo_ra, Fifo_data_err_empty, Fifo_data_err_full },
+ { 2'b0, Dout_BE, Tx_mac_wa, Tx_mac_wr, Tx_mac_sop, Tx_mac_eop} };
+
+ assign debug1 =
+ { { 8'd0 },
+ { 8'd0 },
+ { 8'd0 },
+ { 8'd0 } };
+
+endmodule // MAC_tx_FF
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v b/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v new file mode 100644 index 000000000..76026ce06 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v @@ -0,0 +1,128 @@ +// ////////////////////////////////////////////////////////////////////
+// // ////
+// // MAC_tx_addr_add.v ////
+// // ////
+// // This file is part of the Ethernet IP core project ////
+// // http://www.opencores.org/projects.cgi/wr_en/ethernet_tri_mode/////
+// // ////
+// // Author(s): ////
+// // - Jon Gao (gaojon@yahoo.com) ////
+// // ////
+// // ////
+// ////////////////////////////////////////////////////////////////////
+// // ////
+// // Copyright (C) 2001 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: MAC_tx_addr_add.v,v $
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:18 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module MAC_tx_addr_add
+ (Reset ,
+ Clk ,
+ MAC_tx_addr_init ,
+ MAC_tx_addr_rd ,
+ MAC_tx_addr_data ,
+ //CPU ,
+ MAC_add_prom_data ,
+ MAC_add_prom_add ,
+ MAC_add_prom_wr
+ );
+
+ input Reset ;
+ input Clk ;
+ input MAC_tx_addr_rd ;
+ input MAC_tx_addr_init ;
+ output [7:0] MAC_tx_addr_data ;
+ //CPU ;
+ input [7:0] MAC_add_prom_data ;
+ input [2:0] MAC_add_prom_add ;
+ input MAC_add_prom_wr ;
+
+ // ******************************************************************************
+ // internal signals
+ // ******************************************************************************
+ reg [2:0] add_rd;
+ wire [2:0] add_wr;
+ wire [7:0] din;
+ //wire [7:0] dout;
+ reg [7:0] dout;
+ wire wr_en;
+ reg MAC_add_prom_wr_dl1;
+ reg MAC_add_prom_wr_dl2;
+ // ******************************************************************************
+ // write data from cpu to prom
+ // ******************************************************************************
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ MAC_add_prom_wr_dl1 <=0;
+ MAC_add_prom_wr_dl2 <=0;
+ end
+ else
+ begin
+ MAC_add_prom_wr_dl1 <=MAC_add_prom_wr;
+ MAC_add_prom_wr_dl2 <=MAC_add_prom_wr_dl1;
+ end
+
+ assign wr_en =MAC_add_prom_wr_dl1&!MAC_add_prom_wr_dl2;
+ assign add_wr =MAC_add_prom_add;
+ assign din =MAC_add_prom_data;
+
+ // ******************************************************************************
+ // read data from cpu to prom
+ // ******************************************************************************
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ add_rd <=0;
+ else if (MAC_tx_addr_init)
+ add_rd <=0;
+ else if (MAC_tx_addr_rd)
+ add_rd <=add_rd + 1;
+ assign MAC_tx_addr_data=dout;
+ // ******************************************************************************
+ // b port for read ,a port for write .
+ // ******************************************************************************
+
+ reg [7:0] address_ram [0:7];
+ always @(posedge Clk)
+ if(wr_en)
+ address_ram[add_wr] <= din;
+
+ always @(posedge Clk)
+ dout <= address_ram[add_rd];
+
+endmodule // MAC_tx_addr_add
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v b/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v new file mode 100644 index 000000000..0fd7c603e --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v @@ -0,0 +1,648 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// MAC_tx_ctrl.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: MAC_tx_Ctrl.v,v $
+// Revision 1.4 2006/06/25 04:58:56 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.3 2005/12/16 06:44:17 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.2 2005/12/13 12:15:38 Administrator
+// no message
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module MAC_tx_ctrl (
+Reset ,
+Clk ,
+//CRC_gen Interface
+CRC_init ,
+Frame_data ,
+Data_en ,
+CRC_rd ,
+CRC_end ,
+CRC_out ,
+//Ramdon_gen interfac
+Random_init ,
+RetryCnt ,
+Random_time_meet ,
+//flow control
+pause_apply ,
+pause_quanta_sub ,
+xoff_gen ,
+xoff_gen_complete ,
+xon_gen ,
+xon_gen_complete ,
+//MAC_tx_FF
+Fifo_data ,
+Fifo_rd ,
+Fifo_eop ,
+Fifo_da ,
+Fifo_rd_finish ,
+Fifo_rd_retry ,
+Fifo_ra ,
+Fifo_data_err_empty ,
+Fifo_data_err_full ,
+//RMII
+TxD ,
+TxEn ,
+CRS ,
+//MAC_tx_addr_add
+MAC_tx_addr_rd ,
+MAC_tx_addr_data ,
+MAC_tx_addr_init ,
+//RMON
+Tx_pkt_type_rmon ,
+Tx_pkt_length_rmon ,
+Tx_apply_rmon ,
+Tx_pkt_err_type_rmon,
+//CPU
+pause_quanta_set ,
+MAC_tx_add_en ,
+FullDuplex ,
+MaxRetry ,
+IFGset
+);
+
+input Reset ;
+input Clk ;
+ //CRC_gen Interface
+output CRC_init ;
+output [7:0] Frame_data ;
+output Data_en ;
+output CRC_rd ;
+input CRC_end ;
+input [7:0] CRC_out ;
+ //Ramdon_gen interface
+output Random_init ;
+output [3:0] RetryCnt ;
+input Random_time_meet ;//levle hight indicate random time passed away
+ //flow control
+input pause_apply ;
+output pause_quanta_sub ;
+input xoff_gen ;
+output xoff_gen_complete ;
+input xon_gen ;
+output xon_gen_complete ;
+ //MAC_rx_FF
+input [7:0] Fifo_data ;
+output Fifo_rd ;
+input Fifo_eop ;
+input Fifo_da ;
+output Fifo_rd_finish ;
+output Fifo_rd_retry ;
+input Fifo_ra ;
+input Fifo_data_err_empty ;
+input Fifo_data_err_full ;
+ //RMII
+output [7:0] TxD ;
+output TxEn ;
+input CRS ;
+ //MAC_tx_addr_add
+output MAC_tx_addr_init ;
+output MAC_tx_addr_rd ;
+input [7:0] MAC_tx_addr_data ;
+ //RMON
+output [2:0] Tx_pkt_type_rmon ;
+output [15:0] Tx_pkt_length_rmon ;
+output Tx_apply_rmon ;
+output [2:0] Tx_pkt_err_type_rmon;
+ //CPU
+input [15:0] pause_quanta_set ;
+input MAC_tx_add_en ;
+input FullDuplex ;
+input [3:0] MaxRetry ;
+input [5:0] IFGset ;
+//******************************************************************************
+//internal signals
+//******************************************************************************
+parameter StateIdle =4'd00;
+parameter StatePreamble =4'd01;
+parameter StateSFD =4'd02;
+parameter StateData =4'd03;
+parameter StatePause =4'd04;
+parameter StatePAD =4'd05;
+parameter StateFCS =4'd06;
+parameter StateIFG =4'd07;
+parameter StateJam =4'd08;
+parameter StateBackOff =4'd09;
+parameter StateJamDrop =4'd10;
+parameter StateFFEmptyDrop =4'd11;
+parameter StateSwitchNext =4'd12;
+parameter StateDefer =4'd13;
+parameter StateSendPauseFrame =4'd14;
+
+reg [3:0] Current_state;
+reg [3:0] Next_state;
+reg [5:0] IFG_counter;
+reg [4:0] Preamble_counter;//
+reg [7:0] TxD_tmp ;
+reg TxEn_tmp ;
+reg [15:0] Tx_pkt_length_rmon ;
+reg Tx_apply_rmon ;
+reg [2:0] Tx_pkt_err_type_rmon;
+reg [3:0] RetryCnt ;
+reg Random_init ;
+reg Fifo_rd_finish ;
+reg Fifo_rd_retry ;
+reg [7:0] TxD ;
+reg TxEn ;
+reg CRC_init ;
+reg Data_en ;
+reg CRC_rd ;
+reg Fifo_rd ;
+reg MAC_tx_addr_rd ;
+reg MAC_header_slot ;
+reg MAC_header_slot_tmp ;
+reg [2:0] Tx_pkt_type_rmon ;
+wire Collision ;
+reg MAC_tx_addr_init ;
+reg Src_MAC_ptr ;
+reg [7:0] IPLengthCounter ;//for pad append
+reg [1:0] PADCounter ;
+reg [7:0] JamCounter ;
+reg PktDrpEvenPtr ;
+reg [7:0] pause_counter ;
+reg pause_quanta_sub ;
+reg [15:0] pause_quanta_set_dl1 ;
+reg xoff_gen_complete ;
+reg xon_gen_complete ;
+//******************************************************************************
+//boundery signal processing
+//******************************************************************************
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ pause_quanta_set_dl1 <=0;
+ end
+ else
+ begin
+ pause_quanta_set_dl1 <=pause_quanta_set ;
+ end
+//******************************************************************************
+//state machine
+//******************************************************************************
+assign Collision=TxEn&CRS;
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ IPLengthCounter <=0;
+ else if (Current_state==StateDefer)
+ IPLengthCounter <=0;
+ else if (IPLengthCounter!=8'hff&&(Current_state==StateData||Current_state==StateSendPauseFrame||Current_state==StatePAD))
+ IPLengthCounter <=IPLengthCounter+1;
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ PADCounter <=0;
+ else if (Current_state!=StatePAD)
+ PADCounter <=0;
+ else
+ PADCounter <=PADCounter+1;
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ Current_state <=StateDefer;
+ else
+ Current_state <=Next_state;
+
+always @ (*)
+ case (Current_state)
+ StateDefer:
+ if ((FullDuplex)||(!FullDuplex&&!CRS))
+ Next_state=StateIFG;
+ else
+ Next_state=Current_state;
+ StateIFG:
+ if (!FullDuplex&&CRS)
+ Next_state=StateDefer;
+ else if ((FullDuplex&&IFG_counter==IFGset-4)||(!FullDuplex&&!CRS&&IFG_counter==IFGset-4))//remove some additional time
+ Next_state=StateIdle;
+ else
+ Next_state=Current_state;
+ StateIdle:
+ if (!FullDuplex&&CRS)
+ Next_state=StateDefer;
+ else if (xoff_gen||xon_gen)
+ Next_state=StatePreamble;
+ else if (pause_apply)
+ Next_state=StatePause;
+ else if ((FullDuplex||~CRS)&&Fifo_ra)
+ Next_state=StatePreamble;
+ else
+ Next_state=Current_state;
+ StatePause:
+ if (pause_counter==512/8)
+ Next_state=StateDefer;
+ else if (xoff_gen||xon_gen)
+ Next_state=StateIdle;
+ else
+ Next_state=Current_state;
+ StatePreamble:
+ if (!FullDuplex&&Collision)
+ Next_state=StateJam;
+ else if ((FullDuplex&&Preamble_counter==6)||(!FullDuplex&&!Collision&&Preamble_counter==6))
+ Next_state=StateSFD;
+ else
+ Next_state=Current_state;
+ StateSFD:
+ if (!FullDuplex&&Collision)
+ Next_state=StateJam;
+ else if (xoff_gen||xon_gen)
+ Next_state=StateSendPauseFrame;
+ else
+ Next_state=StateData;
+ StateSendPauseFrame:
+ if (IPLengthCounter==17)
+ Next_state=StatePAD;
+ else
+ Next_state=Current_state;
+ StateData:
+ if (!FullDuplex&&Collision)
+ Next_state=StateJam;
+ else if (Fifo_data_err_empty)
+ Next_state=StateFFEmptyDrop;
+ else if (Fifo_eop&&IPLengthCounter>=59)//IP+MAC+TYPE=60 ,start from 0
+ Next_state=StateFCS;
+ else if (Fifo_eop)
+ Next_state=StatePAD;
+ else
+ Next_state=StateData;
+ StatePAD:
+ if (!FullDuplex&&Collision)
+ Next_state=StateJam;
+ else if (IPLengthCounter>=59)
+ Next_state=StateFCS;
+ else
+ Next_state=Current_state;
+ StateJam:
+ if (RetryCnt<=MaxRetry&&JamCounter==16)
+ Next_state=StateBackOff;
+ else if (RetryCnt>MaxRetry)
+ Next_state=StateJamDrop;
+ else
+ Next_state=Current_state;
+ StateBackOff:
+ if (Random_time_meet)
+ Next_state =StateDefer;
+ else
+ Next_state =Current_state;
+ StateFCS:
+ if (!FullDuplex&&Collision)
+ Next_state =StateJam;
+ else if (CRC_end)
+ Next_state =StateSwitchNext;
+ else
+ Next_state =Current_state;
+ StateFFEmptyDrop:
+ if (Fifo_eop)
+ Next_state =StateSwitchNext;
+ else
+ Next_state =Current_state;
+ StateJamDrop:
+ if (Fifo_eop)
+ Next_state =StateSwitchNext;
+ else
+ Next_state =Current_state;
+ StateSwitchNext:
+ Next_state =StateDefer;
+ default:
+ Next_state =StateDefer;
+ endcase
+
+
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ JamCounter <=0;
+ else if (Current_state!=StateJam)
+ JamCounter <=0;
+ else if (Current_state==StateJam)
+ JamCounter <=JamCounter+1;
+
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ RetryCnt <=0;
+ else if (Current_state==StateSwitchNext)
+ RetryCnt <=0;
+ else if (Current_state==StateJam&&Next_state==StateBackOff)
+ RetryCnt <=RetryCnt + 1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ IFG_counter <=0;
+ else if (Current_state!=StateIFG)
+ IFG_counter <=0;
+ else
+ IFG_counter <=IFG_counter + 1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Preamble_counter <=0;
+ else if (Current_state!=StatePreamble)
+ Preamble_counter <=0;
+ else
+ Preamble_counter <=Preamble_counter+ 1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ PktDrpEvenPtr <=0;
+ else if(Current_state==StateJamDrop||Current_state==StateFFEmptyDrop)
+ PktDrpEvenPtr <=~PktDrpEvenPtr;
+//******************************************************************************
+//generate output signals
+//******************************************************************************
+//CRC related
+always @(Current_state)
+ if (Current_state==StateSFD)
+ CRC_init =1;
+ else
+ CRC_init =0;
+
+assign Frame_data=TxD_tmp;
+
+always @(Current_state)
+ if (Current_state==StateData||Current_state==StateSendPauseFrame||Current_state==StatePAD)
+ Data_en =1;
+ else
+ Data_en =0;
+
+always @(Current_state)
+ if (Current_state==StateFCS)
+ CRC_rd =1;
+ else
+ CRC_rd =0;
+
+//Ramdon_gen interface
+always @(Current_state or Next_state)
+ if (Current_state==StateJam&&Next_state==StateBackOff)
+ Random_init =1;
+ else
+ Random_init =0;
+
+//MAC_rx_FF
+//data have one cycle delay after fifo read signals
+always @ (*)
+ if (Current_state==StateData ||
+ Current_state==StateSFD&&!(xoff_gen||xon_gen) ||
+ Current_state==StateJamDrop&&PktDrpEvenPtr||
+ Current_state==StateFFEmptyDrop&&PktDrpEvenPtr )
+ Fifo_rd =1;
+ else
+ Fifo_rd =0;
+
+always @ (Current_state)
+ if (Current_state==StateSwitchNext)
+ Fifo_rd_finish =1;
+ else
+ Fifo_rd_finish =0;
+
+always @ (Current_state)
+ if (Current_state==StateJam)
+ Fifo_rd_retry =1;
+ else
+ Fifo_rd_retry =0;
+//RMII
+always @(Current_state)
+ if (Current_state==StatePreamble||Current_state==StateSFD||
+ Current_state==StateData||Current_state==StateSendPauseFrame||
+ Current_state==StateFCS||Current_state==StatePAD||Current_state==StateJam)
+ TxEn_tmp =1;
+ else
+ TxEn_tmp =0;
+
+//gen txd data
+always @(*)
+ case (Current_state)
+ StatePreamble:
+ TxD_tmp =8'h55;
+ StateSFD:
+ TxD_tmp =8'hd5;
+ StateData:
+ if (Src_MAC_ptr&&MAC_tx_add_en)
+ TxD_tmp =MAC_tx_addr_data;
+ else
+ TxD_tmp =Fifo_data;
+ StateSendPauseFrame:
+ if (Src_MAC_ptr&&MAC_tx_add_en)
+ TxD_tmp =MAC_tx_addr_data;
+ else
+ case (IPLengthCounter)
+ 8'd0: TxD_tmp =8'h01;
+ 8'd1: TxD_tmp =8'h80;
+ 8'd2: TxD_tmp =8'hc2;
+ 8'd3: TxD_tmp =8'h00;
+ 8'd4: TxD_tmp =8'h00;
+ 8'd5: TxD_tmp =8'h01;
+ 8'd12: TxD_tmp =8'h88;//type
+ 8'd13: TxD_tmp =8'h08;//
+ 8'd14: TxD_tmp =8'h00;//opcode
+ 8'd15: TxD_tmp =8'h01;
+ 8'd16: TxD_tmp =xon_gen?8'b0:pause_quanta_set_dl1[15:8];
+ 8'd17: TxD_tmp =xon_gen?8'b0:pause_quanta_set_dl1[7:0];
+// 8'd60: TxD_tmp =8'h26;
+// 8'd61: TxD_tmp =8'h6b;
+// 8'd62: TxD_tmp =8'hae;
+// 8'd63: TxD_tmp =8'h0a;
+ default:TxD_tmp =0;
+ endcase
+
+ StatePAD:
+ TxD_tmp =8'h00;
+ StateJam:
+ TxD_tmp =8'h01; //jam sequence
+ StateFCS:
+ TxD_tmp =CRC_out;
+ default:
+ TxD_tmp =2'b0;
+ endcase
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ TxD <=0;
+ TxEn <=0;
+ end
+ else
+ begin
+ TxD <=TxD_tmp;
+ TxEn <=TxEn_tmp;
+ end
+//RMON
+
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Tx_pkt_length_rmon <=0;
+ else if (Current_state==StateSFD)
+ Tx_pkt_length_rmon <=0;
+ else if (Current_state==StateData||Current_state==StateSendPauseFrame||Current_state==StatePAD||Current_state==StateFCS)
+ Tx_pkt_length_rmon <=Tx_pkt_length_rmon+1;
+
+
+reg [2:0] Tx_apply_rmon_reg;
+
+always @( posedge Clk or posedge Reset )
+ if ( Reset )
+ begin
+ Tx_apply_rmon <= 0;
+ Tx_apply_rmon_reg <= 'b0;
+ end
+ else
+ begin
+ if ( (Fifo_eop&&Current_state==StateJamDrop) ||
+ (Fifo_eop&&Current_state==StateFFEmptyDrop) ||
+ CRC_end )
+ Tx_apply_rmon <= 1;
+ else
+ if ( Tx_apply_rmon_reg[2] )
+ Tx_apply_rmon <= 0;
+
+ Tx_apply_rmon_reg <= { Tx_apply_rmon_reg[1:0], Tx_apply_rmon };
+ end
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Tx_pkt_err_type_rmon <=0;
+ else if(Fifo_eop&&Current_state==StateJamDrop)
+ Tx_pkt_err_type_rmon <=3'b001;//
+ else if(Fifo_eop&&Current_state==StateFFEmptyDrop)
+ Tx_pkt_err_type_rmon <=3'b010;//underflow
+ else if(Fifo_eop&&Fifo_data_err_full)
+ Tx_pkt_err_type_rmon <=3'b011;//overflow
+ else if(CRC_end)
+ Tx_pkt_err_type_rmon <=3'b100;//normal
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ MAC_header_slot_tmp <=0;
+ else if(Current_state==StateSFD&&Next_state==StateData)
+ MAC_header_slot_tmp <=1;
+ else
+ MAC_header_slot_tmp <=0;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ MAC_header_slot <=0;
+ else
+ MAC_header_slot <=MAC_header_slot_tmp;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Tx_pkt_type_rmon <=0;
+ else if (Current_state==StateSendPauseFrame)
+ Tx_pkt_type_rmon <=3'b100;
+ else if(MAC_header_slot)
+ Tx_pkt_type_rmon <={1'b0,TxD[7:6]};
+
+
+always @(Tx_pkt_length_rmon)
+ if (Tx_pkt_length_rmon>=6&&Tx_pkt_length_rmon<=11)
+ Src_MAC_ptr =1;
+ else
+ Src_MAC_ptr =0;
+
+//MAC_tx_addr_add
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ MAC_tx_addr_rd <=0;
+ else if ((Tx_pkt_length_rmon>=4&&Tx_pkt_length_rmon<=9)&&(MAC_tx_add_en||Current_state==StateSendPauseFrame))
+ MAC_tx_addr_rd <=1;
+ else
+ MAC_tx_addr_rd <=0;
+
+ always @*
+ //if ((Tx_pkt_length_rmon==3)&&Fifo_rd)
+ if (Current_state==StatePreamble)
+ MAC_tx_addr_init=1;
+ else
+ MAC_tx_addr_init=0;
+
+//**************************************************************************************************************
+// CFH: this implementation delays the time it sends an entire Ethernet frame with 512 bits for every pause
+// request of 512 bits. Actually, it should only delay the time it takes to transmit 512 bits, not counting
+// Ethernet header, CRC, Interframe Gap etc.
+// Hence the current implementation waits longer than the pause frame actually requests (~20% more)
+//**************************************************************************************************************
+
+//flow control
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ pause_counter <=0;
+ else if (Current_state!=StatePause)
+ pause_counter <=0;
+ else
+ pause_counter <=pause_counter+1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ pause_quanta_sub <=0;
+ else if(pause_counter==512/8)
+ pause_quanta_sub <=1;
+ else
+ pause_quanta_sub <=0;
+
+// FIXME The below probably won't work if the pause request comes when we are in the wrong state
+ wire clear_xonxoff = (Current_state==StateSendPauseFrame) & (IPLengthCounter==17);
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ xoff_gen_complete <=0;
+ else if(clear_xonxoff & xoff_gen)
+ xoff_gen_complete <=1;
+ else
+ xoff_gen_complete <=0;
+
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ xon_gen_complete <=0;
+ else if(clear_xonxoff & xon_gen)
+ xon_gen_complete <=1;
+ else
+ xon_gen_complete <=0;
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/MAC_tx/Random_gen.v b/usrp2/fpga/eth/rtl/verilog/MAC_tx/Random_gen.v new file mode 100644 index 000000000..fd57008b1 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/MAC_tx/Random_gen.v @@ -0,0 +1,109 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// Random_gen.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module Random_gen(
+Reset ,
+Clk ,
+Init ,
+RetryCnt ,
+Random_time_meet
+);
+input Reset ;
+input Clk ;
+input Init ;
+input [3:0] RetryCnt ;
+output Random_time_meet;
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+reg [9:0] Random_sequence ;
+reg [9:0] Random ;
+reg [9:0] Random_counter ;
+reg [7:0] Slot_time_counter; //256*2=512bit=1 slot time
+reg Random_time_meet;
+
+//******************************************************************************
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Random_sequence <=0;
+ else
+ Random_sequence <={Random_sequence[8:0],~(Random_sequence[2]^Random_sequence[9])};
+
+always @ (RetryCnt or Random_sequence)
+ case (RetryCnt)
+ 4'h0 : Random={9'b0,Random_sequence[0]};
+ 4'h1 : Random={8'b0,Random_sequence[1:0]};
+ 4'h2 : Random={7'b0,Random_sequence[2:0]};
+ 4'h3 : Random={6'b0,Random_sequence[3:0]};
+ 4'h4 : Random={5'b0,Random_sequence[4:0]};
+ 4'h5 : Random={4'b0,Random_sequence[5:0]};
+ 4'h6 : Random={3'b0,Random_sequence[6:0]};
+ 4'h7 : Random={2'b0,Random_sequence[7:0]};
+ 4'h8 : Random={1'b0,Random_sequence[8:0]};
+ 4'h9 : Random={ Random_sequence[9:0]};
+ default : Random={ Random_sequence[9:0]};
+ endcase
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Slot_time_counter <=0;
+ else if(Init)
+ Slot_time_counter <=0;
+ else if(!Random_time_meet)
+ Slot_time_counter <=Slot_time_counter+1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Random_counter <=0;
+ else if (Init)
+ Random_counter <=Random;
+ else if (Random_counter!=0&&Slot_time_counter==255)
+ Random_counter <=Random_counter -1 ;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Random_time_meet <=1;
+ else if (Init)
+ Random_time_meet <=0;
+ else if (Random_counter==0)
+ Random_time_meet <=1;
+
+endmodule
+
+
diff --git a/usrp2/fpga/eth/rtl/verilog/Phy_int.v b/usrp2/fpga/eth/rtl/verilog/Phy_int.v new file mode 100644 index 000000000..c85d4f64b --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/Phy_int.v @@ -0,0 +1,205 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// Phy_int.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: Phy_int.v,v $
+// Revision 1.3 2006/01/19 14:07:53 maverickist
+// verification is complete.
+//
+// Revision 1.3 2005/12/16 06:44:14 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.2 2005/12/13 12:15:36 Administrator
+// no message
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+module Phy_int
+ (input rst_mac_rx,
+ input rst_mac_tx,
+ input MAC_rx_clk,
+ input MAC_tx_clk,
+
+ // Rx interface
+ output reg MCrs_dv,
+ output reg [7:0] MRxD,
+ output MRxErr,
+
+ // Tx interface
+ input [7:0] MTxD,
+ input MTxEn,
+ output MCRS,
+
+ // PHY interface
+ output Tx_er,
+ output reg Tx_en,
+ output reg [7:0] Txd,
+ input Rx_er,
+ input Rx_dv,
+ input [7:0] Rxd,
+ input Crs,
+ input Col,
+
+ // Host interface
+ input Line_loop_en,
+ input [2:0] Speed );
+
+ //-------------------------------------------------------------------------
+ // Local declarations
+ //-------------------------------------------------------------------------
+
+ reg [7:0] MTxD_dl1;
+ reg MTxEn_dl1;
+ reg Tx_odd_data_ptr;
+ reg Rx_odd_data_ptr;
+ reg Rx_er_dl1;
+ reg Rx_dv_dl1;
+ reg Rx_dv_dl2;
+ reg [7:0] Rxd_dl1;
+ reg [7:0] Rxd_dl2;
+ reg Crs_dl1;
+
+ //-------------------------------------------------------------------------
+ // Tx control
+ //-------------------------------------------------------------------------
+
+ // Reg boundary signals
+ always @( posedge MAC_tx_clk or posedge rst_mac_tx )
+ if ( rst_mac_tx )
+ begin
+ MTxD_dl1 <= 0;
+ MTxEn_dl1 <= 0;
+ end
+ else
+ begin
+ MTxD_dl1 <= MTxD;
+ MTxEn_dl1 <= MTxEn;
+ end
+
+ always @( posedge MAC_tx_clk or posedge rst_mac_tx )
+ if ( rst_mac_tx )
+ Tx_odd_data_ptr <= 0;
+ else if ( !MTxD_dl1 )
+ Tx_odd_data_ptr <= 0;
+ else
+ Tx_odd_data_ptr <= !Tx_odd_data_ptr;
+
+
+ always @( posedge MAC_tx_clk or posedge rst_mac_tx )
+ if ( rst_mac_tx )
+ Txd <= 0;
+ else if ( Speed[2] && MTxEn_dl1 )
+ Txd <= MTxD_dl1;
+ else if ( MTxEn_dl1 && !Tx_odd_data_ptr )
+ Txd <= { 4'b0, MTxD_dl1[3:0] };
+ else if ( MTxEn_dl1 && Tx_odd_data_ptr )
+ Txd <= { 4'b0, MTxD_dl1[7:4] };
+ else
+ Txd <=0;
+
+ always @( posedge MAC_tx_clk or posedge rst_mac_tx )
+ if ( rst_mac_tx )
+ Tx_en <= 0;
+ else if ( MTxEn_dl1 )
+ Tx_en <= 1;
+ else
+ Tx_en <= 0;
+
+ assign Tx_er = 0;
+
+ //-------------------------------------------------------------------------
+ // Rx control
+ //-------------------------------------------------------------------------
+
+ // Reg boundery signals
+ always @( posedge MAC_rx_clk or posedge rst_mac_rx )
+ if ( rst_mac_rx )
+ begin
+ Rx_er_dl1 <= 0;
+ Rx_dv_dl1 <= 0;
+ Rx_dv_dl2 <= 0;
+ Rxd_dl1 <= 0;
+ Rxd_dl2 <= 0;
+ Crs_dl1 <= 0;
+ end
+ else
+ begin
+ Rx_er_dl1 <= Rx_er;
+ Rx_dv_dl1 <= Rx_dv;
+ Rx_dv_dl2 <= Rx_dv_dl1;
+ Rxd_dl1 <= Rxd;
+ Rxd_dl2 <= Rxd_dl1;
+ Crs_dl1 <= Crs;
+ end
+
+ assign MRxErr = Rx_er_dl1;
+ assign MCRS = Crs_dl1;
+
+ always @( posedge MAC_rx_clk or posedge rst_mac_rx )
+ if ( rst_mac_rx )
+ MCrs_dv <= 0;
+ else if ( Line_loop_en )
+ MCrs_dv <= Tx_en;
+ else if( Rx_dv_dl2 )
+ MCrs_dv <= 1;
+ else
+ MCrs_dv <= 0;
+
+ always @ ( posedge MAC_rx_clk or posedge rst_mac_rx )
+ if ( rst_mac_rx )
+ Rx_odd_data_ptr <= 0;
+ else if ( !Rx_dv_dl1 )
+ Rx_odd_data_ptr <= 0;
+ else
+ Rx_odd_data_ptr <= !Rx_odd_data_ptr;
+
+ always @ ( posedge MAC_rx_clk or posedge rst_mac_rx )
+ if ( rst_mac_rx )
+ MRxD <= 0;
+ else if( Line_loop_en )
+ MRxD <= Txd;
+ else if( Speed[2] && Rx_dv_dl2 )
+ MRxD <= Rxd_dl2;
+ else if( Rx_dv_dl1 && Rx_odd_data_ptr )
+ MRxD <={ Rxd_dl1[3:0], Rxd_dl2[3:0] };
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/RMON.v b/usrp2/fpga/eth/rtl/verilog/RMON.v new file mode 100644 index 000000000..18a84beb5 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/RMON.v @@ -0,0 +1,163 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// RMON.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: RMON.v,v $
+// Revision 1.4 2006/06/25 04:58:56 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:53 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:16 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+module RMON
+ (input Clk ,
+ input Reset ,
+ //Tx_RMON
+ input [2:0] Tx_pkt_type_rmon ,
+ input [15:0] Tx_pkt_length_rmon ,
+ input Tx_apply_rmon ,
+ input [2:0] Tx_pkt_err_type_rmon,
+ //Tx_RMON
+ input [2:0] Rx_pkt_type_rmon ,
+ input [15:0] Rx_pkt_length_rmon ,
+ input Rx_apply_rmon ,
+ input [2:0] Rx_pkt_err_type_rmon,
+ //CPU
+ input [5:0] CPU_rd_addr ,
+ input CPU_rd_apply ,
+ output CPU_rd_grant ,
+ output [31:0] CPU_rd_dout
+ );
+
+ // ******************************************************************************
+ // interface signals
+ // ******************************************************************************
+ wire Reg_apply_0 ;
+ wire [4:0] Reg_addr_0 ;
+ wire [15:0] Reg_data_0 ;
+ wire Reg_next_0 ;
+ wire Reg_apply_1 ;
+ wire [4:0] Reg_addr_1 ;
+ wire [15:0] Reg_data_1 ;
+ wire Reg_next_1 ;
+ wire [5:0] Addra ;
+ wire [31:0] Dina ;
+ reg [31:0] Douta ;
+ wire Wea ;
+
+ // ******************************************************************************
+
+ RMON_addr_gen U_0_Rx_RMON_addr_gen
+ (.Clk (Clk ),
+ .Reset (Reset ),
+ //RMON
+ .Pkt_type_rmon (Rx_pkt_type_rmon ),
+ .Pkt_length_rmon (Rx_pkt_length_rmon ),
+ .Apply_rmon (Rx_apply_rmon ),
+ .Pkt_err_type_rmon (Rx_pkt_err_type_rmon ),
+ //Rmon_ctrl
+ .Reg_apply (Reg_apply_0 ),
+ .Reg_addr (Reg_addr_0 ),
+ .Reg_data (Reg_data_0 ),
+ .Reg_next (Reg_next_0 ),
+ //CPU
+ .Reg_drop_apply ( ) );
+
+ RMON_addr_gen U_0_Tx_RMON_addr_gen
+ (.Clk (Clk ),
+ .Reset (Reset ),
+ //RMON
+ .Pkt_type_rmon (Tx_pkt_type_rmon ),
+ .Pkt_length_rmon (Tx_pkt_length_rmon ),
+ .Apply_rmon (Tx_apply_rmon ),
+ .Pkt_err_type_rmon (Tx_pkt_err_type_rmon ),
+ //Rmon_ctrl
+ .Reg_apply (Reg_apply_1 ),
+ .Reg_addr (Reg_addr_1 ),
+ .Reg_data (Reg_data_1 ),
+ .Reg_next (Reg_next_1 ),
+ //CPU
+ .Reg_drop_apply ( ) );
+
+ RMON_ctrl U_RMON_ctrl
+ (.Clk (Clk ),
+ .Reset (Reset ),
+ //RMON_ctrl
+ .Reg_apply_0 (Reg_apply_0 ),
+ .Reg_addr_0 (Reg_addr_0 ),
+ .Reg_data_0 (Reg_data_0 ),
+ .Reg_next_0 (Reg_next_0 ),
+ .Reg_apply_1 (Reg_apply_1 ),
+ .Reg_addr_1 (Reg_addr_1 ),
+ .Reg_data_1 (Reg_data_1 ),
+ .Reg_next_1 (Reg_next_1 ),
+ //dual-port ram
+ .Addra (Addra ),
+ .Dina (Dina ),
+ .Douta (Douta ),
+ .Wea (Wea ),
+ //CPU
+ .CPU_rd_addr (CPU_rd_addr ),
+ .CPU_rd_apply (CPU_rd_apply ),
+ .CPU_rd_grant (CPU_rd_grant ),
+ .CPU_rd_dout (CPU_rd_dout ) );
+
+ reg [31:0] RMON_ram [0:63];
+ wire [31:0] Douta_imm = RMON_ram[Addra];
+ integer i;
+ initial
+ for(i=0;i<64;i=i+1)
+ RMON_ram[i] = 32'd0;
+
+ always @(posedge Clk)
+ if(Wea)
+ RMON_ram[Addra] <= Dina;
+
+ always @(posedge Clk)
+ Douta <= Douta_imm;
+
+endmodule // RMON
diff --git a/usrp2/fpga/eth/rtl/verilog/RMON/RMON_addr_gen.v b/usrp2/fpga/eth/rtl/verilog/RMON/RMON_addr_gen.v new file mode 100644 index 000000000..9da8d1f80 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/RMON/RMON_addr_gen.v @@ -0,0 +1,295 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// RMON_addr_gen.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: RMON_addr_gen.v,v $
+// Revision 1.4 2006/06/25 04:58:57 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:55 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:19 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+module RMON_addr_gen(
+Clk ,
+Reset ,
+//RMON
+Pkt_type_rmon ,
+Pkt_length_rmon ,
+Apply_rmon ,//pluse signal looks like eop
+Pkt_err_type_rmon ,
+//
+Reg_apply ,
+Reg_addr ,
+Reg_data ,
+Reg_next ,
+//CPU
+Reg_drop_apply
+);
+input Clk ;
+input Reset ;
+ //RMON
+input [2:0] Pkt_type_rmon ;
+input [15:0] Pkt_length_rmon ;
+input Apply_rmon ;//pluse signal looks like eop
+input [2:0] Pkt_err_type_rmon ;
+ //RMON_ctrl
+output Reg_apply ;
+output [4:0] Reg_addr ;
+output [15:0] Reg_data ;
+input Reg_next ;
+ //CPU
+output Reg_drop_apply ;
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+parameter StateIdle =4'd0;
+parameter StatePktLength =4'd1;
+parameter StatePktNumber =4'd2;
+parameter StatePktType =4'd3;
+parameter StatePktRange =4'd4;
+
+reg [3:0] CurrentState /* synthesys syn_keep=1 */;
+reg [3:0] NextState;
+
+reg [2:0] PktTypeReg ;
+reg [15:0] PktLengthReg ;
+reg [2:0] PktErrTypeReg ;
+
+reg Reg_apply ;
+reg [4:0] Reg_addr ;
+reg [15:0] Reg_data ;
+reg Reg_drop_apply ;
+//******************************************************************************
+//register boundery signals
+
+//******************************************************************************
+reg Apply_rmon_dl1;
+reg Apply_rmon_dl2;
+reg Apply_rmon_pulse;
+reg [2:0] Pkt_type_rmon_dl1 ;
+reg [15:0] Pkt_length_rmon_dl1 ;
+reg [2:0] Pkt_err_type_rmon_dl1 ;
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ Pkt_type_rmon_dl1 <=0;
+ Pkt_length_rmon_dl1 <=0;
+ Pkt_err_type_rmon_dl1 <=0;
+ end
+ else
+ begin
+ Pkt_type_rmon_dl1 <=Pkt_type_rmon ;
+ Pkt_length_rmon_dl1 <=Pkt_length_rmon ;
+ Pkt_err_type_rmon_dl1 <=Pkt_err_type_rmon ;
+ end
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ Apply_rmon_dl1 <=0;
+ Apply_rmon_dl2 <=0;
+ end
+ else
+ begin
+ Apply_rmon_dl1 <=Apply_rmon;
+ Apply_rmon_dl2 <=Apply_rmon_dl1;
+ end
+
+always @(Apply_rmon_dl1 or Apply_rmon_dl2)
+ if (Apply_rmon_dl1&!Apply_rmon_dl2)
+ Apply_rmon_pulse =1;
+ else
+ Apply_rmon_pulse =0;
+
+
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ PktTypeReg <=0;
+ PktLengthReg <=0;
+ PktErrTypeReg <=0;
+ end
+ else if (Apply_rmon_pulse&&CurrentState==StateIdle)
+ begin
+ PktTypeReg <=Pkt_type_rmon_dl1 ;
+ PktLengthReg <=Pkt_length_rmon_dl1 ;
+ PktErrTypeReg <=Pkt_err_type_rmon_dl1 ;
+ end
+
+
+//******************************************************************************
+//State Machine
+//******************************************************************************
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ CurrentState <=StateIdle;
+ else
+ CurrentState <=NextState;
+
+always @(CurrentState or Apply_rmon_pulse or Reg_next)
+ case (CurrentState)
+ StateIdle:
+ if (Apply_rmon_pulse)
+ NextState =StatePktLength;
+ else
+ NextState =StateIdle;
+ StatePktLength:
+ if (Reg_next)
+ NextState =StatePktNumber;
+ else
+ NextState =CurrentState;
+ StatePktNumber:
+ if (Reg_next)
+ NextState =StatePktType;
+ else
+ NextState =CurrentState;
+ StatePktType:
+ if (Reg_next)
+ NextState =StatePktRange;
+ else
+ NextState =CurrentState;
+ StatePktRange:
+ if (Reg_next)
+ NextState =StateIdle;
+ else
+ NextState =CurrentState;
+ default:
+ NextState =StateIdle;
+ endcase
+
+//******************************************************************************
+//gen output signals
+//******************************************************************************
+//Reg_apply
+always @ (CurrentState)
+ if (CurrentState==StatePktLength||CurrentState==StatePktNumber||
+ CurrentState==StatePktType||CurrentState==StatePktRange)
+ Reg_apply =1;
+ else
+ Reg_apply =0;
+
+//Reg_addr
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Reg_addr <=0;
+ else case (CurrentState)
+ StatePktLength:
+ Reg_addr <=5'd00;
+ StatePktNumber:
+ Reg_addr <=5'd01;
+ StatePktType:
+ case(PktTypeReg)
+ 3'b011:
+ Reg_addr <=5'd02; //broadcast
+ 3'b001:
+ Reg_addr <=5'd03; //multicast
+ 3'b100:
+ Reg_addr <=5'd16; //pause frame
+ default:
+ Reg_addr <=5'd04; //unicast
+ endcase
+ StatePktRange:
+ case(PktErrTypeReg)
+ 3'b001:
+ Reg_addr <=5'd05;
+ 3'b010:
+ Reg_addr <=5'd06;
+ 3'b011:
+ Reg_addr <=5'd07;
+ 3'b100:
+ if (PktLengthReg<64)
+ Reg_addr <=5'd08;
+ else if (PktLengthReg==64)
+ Reg_addr <=5'd09;
+ else if (PktLengthReg<128)
+ Reg_addr <=5'd10;
+ else if (PktLengthReg<256)
+ Reg_addr <=5'd11;
+ else if (PktLengthReg<512)
+ Reg_addr <=5'd12;
+ else if (PktLengthReg<1024)
+ Reg_addr <=5'd13;
+ else if (PktLengthReg<1519)
+ Reg_addr <=5'd14;
+ else
+ Reg_addr <=5'd15;
+ default:
+ Reg_addr <=5'd05;
+ endcase
+ default:
+ Reg_addr <=5'd05;
+ endcase
+
+//Reg_data
+always @ (CurrentState or PktLengthReg)
+ case (CurrentState)
+ StatePktLength:
+ Reg_data =PktLengthReg;
+ StatePktNumber:
+ Reg_data =1;
+ StatePktType:
+ Reg_data =1;
+ StatePktRange:
+ Reg_data =1;
+ default:
+ Reg_data =0;
+ endcase
+
+//Reg_drop_apply
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Reg_drop_apply <=0;
+ else if (CurrentState!=StateIdle&&Apply_rmon_pulse)
+ Reg_drop_apply <=1;
+ else
+ Reg_drop_apply <=0;
+
+
+endmodule
+
diff --git a/usrp2/fpga/eth/rtl/verilog/RMON/RMON_ctrl.v b/usrp2/fpga/eth/rtl/verilog/RMON/RMON_ctrl.v new file mode 100644 index 000000000..4fc038dc8 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/RMON/RMON_ctrl.v @@ -0,0 +1,283 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// RMON_ctrl.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: RMON_ctrl.v,v $
+// Revision 1.4 2006/06/25 04:58:57 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:55 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:19 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+module RMON_ctrl (
+Clk ,
+Reset ,
+//RMON_ctrl
+Reg_apply_0 ,
+Reg_addr_0 ,
+Reg_data_0 ,
+Reg_next_0 ,
+Reg_apply_1 ,
+Reg_addr_1 ,
+Reg_data_1 ,
+Reg_next_1 ,
+//dual-port ram
+Addra ,
+Dina ,
+Douta ,
+Wea ,
+//CPU
+CPU_rd_addr ,
+CPU_rd_apply ,
+CPU_rd_grant ,
+CPU_rd_dout
+
+);
+input Clk ;
+input Reset ;
+ //RMON_ctrl
+input Reg_apply_0 ;
+input [4:0] Reg_addr_0 ;
+input [15:0] Reg_data_0 ;
+output Reg_next_0 ;
+input Reg_apply_1 ;
+input [4:0] Reg_addr_1 ;
+input [15:0] Reg_data_1 ;
+output Reg_next_1 ;
+ //dual-port ram
+ //port-a for Rmon
+output [5:0] Addra ;
+output [31:0] Dina ;
+input [31:0] Douta ;
+output Wea ;
+ //CPU
+input [5:0] CPU_rd_addr ;
+input CPU_rd_apply ;
+output CPU_rd_grant ;
+output [31:0] CPU_rd_dout ;
+
+
+
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+
+parameter StateCPU =4'd00;
+parameter StateMAC0 =4'd01;
+parameter StateMAC1 =4'd02;
+
+
+reg [3:0] CurrentState /* synthesys syn_keep=1 */;
+reg [3:0] NextState;
+reg [3:0] CurrentState_reg;
+
+reg [4:0] StepCounter;
+reg [5:0] Addra ;
+reg [31:0] Dina;
+reg Reg_next_0 ;
+reg Reg_next_1 ;
+reg Write;
+reg Read;
+reg Pipeline;
+reg [31:0] CPU_rd_dout ;
+reg CPU_rd_apply_reg ;
+//******************************************************************************
+//State Machine
+//******************************************************************************
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ CurrentState <=StateMAC0;
+ else
+ CurrentState <=NextState;
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ CurrentState_reg <=StateMAC0;
+ else if(CurrentState!=StateCPU)
+ CurrentState_reg <=CurrentState;
+
+always @(CurrentState or CPU_rd_apply_reg or Reg_apply_0 or CurrentState_reg
+ or Reg_apply_1
+ or StepCounter
+ )
+ case(CurrentState)
+ StateMAC0:
+ if(!Reg_apply_0&&CPU_rd_apply_reg)
+ NextState =StateCPU;
+ else if(!Reg_apply_0)
+ NextState =StateMAC1;
+ else
+ NextState =CurrentState;
+ StateMAC1:
+ if(!Reg_apply_1&&CPU_rd_apply_reg)
+ NextState =StateCPU;
+ else if(!Reg_apply_1)
+ NextState =StateMAC0;
+ else
+ NextState =CurrentState;
+ StateCPU:
+ if (StepCounter==3)
+ case (CurrentState_reg)
+ StateMAC0 :NextState =StateMAC0 ;
+ StateMAC1 :NextState =StateMAC1 ;
+ default :NextState =StateMAC0;
+ endcase
+ else
+ NextState =CurrentState;
+
+ default:
+ NextState =StateMAC0;
+ endcase
+
+
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ StepCounter <=0;
+ else if(NextState!=CurrentState)
+ StepCounter <=0;
+ else if (StepCounter!=4'hf)
+ StepCounter <=StepCounter + 1;
+
+//******************************************************************************
+//temp signals
+//******************************************************************************
+always @(StepCounter)
+ if( StepCounter==1||StepCounter==4||
+ StepCounter==7||StepCounter==10)
+ Read =1;
+ else
+ Read =0;
+
+always @(StepCounter or CurrentState)
+ if( StepCounter==2||StepCounter==5||
+ StepCounter==8||StepCounter==11)
+ Pipeline =1;
+ else
+ Pipeline =0;
+
+always @(StepCounter or CurrentState)
+ if( StepCounter==3||StepCounter==6||
+ StepCounter==9||StepCounter==12)
+ Write =1;
+ else
+ Write =0;
+
+
+//******************************************************************************
+//gen output signals
+//******************************************************************************
+//Addra
+always @(*)
+ case(CurrentState)
+ StateMAC0 : Addra={1'd0 ,Reg_addr_0 };
+ StateMAC1 : Addra={1'd1 ,Reg_addr_1 };
+ StateCPU: Addra=CPU_rd_addr;
+ default: Addra=0;
+ endcase
+
+//Dina
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ Dina <=0;
+ else
+ case(CurrentState)
+ StateMAC0 : Dina<=Douta+Reg_data_0 ;
+ StateMAC1 : Dina<=Douta+Reg_data_1 ;
+ StateCPU: Dina<=0;
+ default: Dina<=0;
+ endcase
+
+assign Wea =Write;
+//Reg_next
+always @(CurrentState or Pipeline)
+ if(CurrentState==StateMAC0)
+ Reg_next_0 =Pipeline;
+ else
+ Reg_next_0 =0;
+
+always @(CurrentState or Pipeline)
+ if(CurrentState==StateMAC1)
+ Reg_next_1 =Pipeline;
+ else
+ Reg_next_1 =0;
+
+
+//CPU_rd_grant
+reg CPU_rd_apply_dl1;
+reg CPU_rd_apply_dl2;
+//rising edge
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ CPU_rd_apply_dl1 <=0;
+ CPU_rd_apply_dl2 <=0;
+ end
+ else
+ begin
+ CPU_rd_apply_dl1 <=CPU_rd_apply;
+ CPU_rd_apply_dl2 <=CPU_rd_apply_dl1;
+ end
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ CPU_rd_apply_reg <=0;
+ else if (CPU_rd_apply_dl1&!CPU_rd_apply_dl2)
+ CPU_rd_apply_reg <=1;
+ else if (CurrentState==StateCPU&&Write)
+ CPU_rd_apply_reg <=0;
+
+assign CPU_rd_grant = CPU_rd_apply & CPU_rd_apply_dl1 & CPU_rd_apply_dl2 & !CPU_rd_apply_reg;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ CPU_rd_dout <=0;
+ else if (Pipeline&&CurrentState==StateCPU)
+ CPU_rd_dout <=Douta;
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/Reg_int.v b/usrp2/fpga/eth/rtl/verilog/Reg_int.v new file mode 100644 index 000000000..f1bea2316 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/Reg_int.v @@ -0,0 +1,270 @@ +module Reg_int (
+ // Wishbone compliant core host interface
+ input CLK_I, // Wishbone interface clock (nominally 50 MHz)
+ input RST_I, // Active high (async) reset of the Wishbone interface
+ input STB_I, // Active high module-select
+ input CYC_I, // Active high cycle-enable
+ input [6:0] ADR_I, // Module register address
+ input WE_I, // Active high for writes, low for reads
+ input [31:0] DAT_I, // Write data
+ output reg [31:0] DAT_O, // Read data
+ output reg ACK_O, // Acknowledge output – single high pulse
+
+ // Tx host interface
+ output [4:0] Tx_Hwmark,
+ output [4:0] Tx_Lwmark,
+ output MAC_tx_add_en,
+ output FullDuplex,
+ output [3:0] MaxRetry,
+ output [5:0] IFGset,
+ output [7:0] MAC_tx_add_prom_data,
+ output [2:0] MAC_tx_add_prom_add,
+ output MAC_tx_add_prom_wr,
+
+ // Rx host interface
+ output MAC_rx_add_chk_en,
+ output [7:0] MAC_rx_add_prom_data,
+ output [2:0] MAC_rx_add_prom_add,
+ output MAC_rx_add_prom_wr,
+ output broadcast_filter_en,
+ output [15:0] broadcast_bucket_depth,
+ output [15:0] broadcast_bucket_interval,
+ output RX_APPEND_CRC,
+ output [4:0] Rx_Hwmark,
+ output [4:0] Rx_Lwmark,
+ output CRC_chk_en,
+ output [5:0] RX_IFG_SET,
+ output [15:0] RX_MAX_LENGTH, // Default 1518
+ output [6:0] RX_MIN_LENGTH, // Default 64
+
+ // Flow control settings
+ output pause_frame_send_en,
+ output [15:0] pause_quanta_set,
+ output tx_pause_en,
+ output [15:0] fc_hwmark,
+ output [15:0] fc_lwmark,
+
+ // RMON host interface
+ output [5:0] CPU_rd_addr,
+ output CPU_rd_apply,
+ input CPU_rd_grant,
+ input [31:0] CPU_rd_dout,
+
+ //Phy int host interface
+ output Line_loop_en,
+ output [2:0] Speed,
+
+ //MII to CPU
+ output [7:0] Divider, // Divider for the host clock
+ output [15:0] CtrlData, // Control Data (to be written to the PHY reg.)
+ output [4:0] Rgad, // Register Address (within the PHY)
+ output [4:0] Fiad, // PHY Address
+ output NoPre, // No Preamble (no 32-bit preamble)
+ output WCtrlData, // Write Control Data operation
+ output RStat, // Read Status operation
+ output ScanStat, // Scan Status operation
+ input Busy, // Busy Signal
+ input LinkFail, // Link Integrity Signal
+ input Nvalid, // Invalid Status (qualifier for the valid scan result)
+ input [15:0] Prsd, // Read Status Data (data read from the PHY)
+ input WCtrlDataStart, // This signals resets the WCTRLDATA bit in the MIIM Command register
+ input RStatStart, // This signal resets the RSTAT BIT in the MIIM Command register
+ input UpdateMIIRX_DATAReg // Updates MII RX_DATA register with read data
+);
+
+ // New registers for controlling the MII interface
+ wire [8:0] MIIMODER;
+ reg [2:0] MIICOMMAND;
+ wire [12:0] MIIADDRESS;
+ wire [15:0] MIITX_DATA;
+ reg [15:0] MIIRX_DATA;
+ wire [2:0] MIISTATUS;
+
+ // New registers for controlling the MII interface
+
+ // MIIMODER
+ assign NoPre = MIIMODER[8];
+ assign Divider = MIIMODER[7:0];
+ // MIICOMMAND
+ assign WCtrlData = MIICOMMAND[2];
+ assign RStat = MIICOMMAND[1];
+ assign ScanStat = MIICOMMAND[0];
+ // MIIADDRESS
+ assign Rgad = MIIADDRESS[12:8];
+ assign Fiad = MIIADDRESS[4:0];
+ // MIITX_DATA
+ assign CtrlData = MIITX_DATA[15:0];
+ // MIISTATUS
+ assign MIISTATUS[2:0] = { 13'b0, Nvalid, Busy, LinkFail };
+
+ wire Wr;
+
+ RegCPUData #( 5 ) U_0_000( Tx_Hwmark , 7'd000, 5'h09, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] );
+ RegCPUData #( 5 ) U_0_001( Tx_Lwmark , 7'd001, 5'h08, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] );
+ RegCPUData #( 1 ) U_0_002( pause_frame_send_en , 7'd002, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 16 ) U_0_003( pause_quanta_set , 7'd003, 16'h01af, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+ RegCPUData #( 6 ) U_0_004( IFGset , 7'd004, 6'h0c, RST_I, CLK_I, Wr, ADR_I, DAT_I[5:0] );
+ RegCPUData #( 1 ) U_0_005( FullDuplex , 7'd005, 1'h1, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 4 ) U_0_006( MaxRetry , 7'd006, 4'h2, RST_I, CLK_I, Wr, ADR_I, DAT_I[3:0] );
+ RegCPUData #( 1 ) U_0_007( MAC_tx_add_en , 7'd007, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 8 ) U_0_008( MAC_tx_add_prom_data , 7'd008, 8'h00, RST_I, CLK_I, Wr, ADR_I, DAT_I[7:0] );
+ RegCPUData #( 3 ) U_0_009( MAC_tx_add_prom_add , 7'd009, 3'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[2:0] );
+ RegCPUData #( 1 ) U_0_010( MAC_tx_add_prom_wr , 7'd010, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 1 ) U_0_011( tx_pause_en , 7'd011, 1'h1, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 16 ) U_0_012( fc_hwmark , 7'd012, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+ RegCPUData #( 16 ) U_0_013( fc_lwmark , 7'd013, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+ RegCPUData #( 1 ) U_0_014( MAC_rx_add_chk_en , 7'd014, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 8 ) U_0_015( MAC_rx_add_prom_data , 7'd015, 8'h00, RST_I, CLK_I, Wr, ADR_I, DAT_I[7:0] );
+ RegCPUData #( 3 ) U_0_016( MAC_rx_add_prom_add , 7'd016, 3'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[2:0] );
+ RegCPUData #( 1 ) U_0_017( MAC_rx_add_prom_wr , 7'd017, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 1 ) U_0_018( broadcast_filter_en , 7'd018, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 16 ) U_0_019( broadcast_bucket_depth , 7'd019, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+ RegCPUData #( 16 ) U_0_020( broadcast_bucket_interval , 7'd020, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+ RegCPUData #( 1 ) U_0_021( RX_APPEND_CRC , 7'd021, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 5 ) U_0_022( Rx_Hwmark , 7'd022, 5'h1a, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] );
+ RegCPUData #( 5 ) U_0_023( Rx_Lwmark , 7'd023, 5'h10, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] );
+ RegCPUData #( 1 ) U_0_024( CRC_chk_en , 7'd024, 1'h1, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 6 ) U_0_025( RX_IFG_SET , 7'd025, 6'h0c, RST_I, CLK_I, Wr, ADR_I, DAT_I[5:0] );
+ RegCPUData #( 16 ) U_0_026( RX_MAX_LENGTH , 7'd026, 16'h2710, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+ RegCPUData #( 7 ) U_0_027( RX_MIN_LENGTH , 7'd027, 7'h40, RST_I, CLK_I, Wr, ADR_I, DAT_I[6:0] );
+ RegCPUData #( 6 ) U_0_028( CPU_rd_addr , 7'd028, 6'h00, RST_I, CLK_I, Wr, ADR_I, DAT_I[5:0] );
+ RegCPUData #( 1 ) U_0_029( CPU_rd_apply , 7'd029, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+//RegCPUData #( 1 ) U_0_030( CPU_rd_grant , 7'd030, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+//RegCPUData #( 16 ) U_0_031( CPU_rd_dout_l , 7'd031, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+//RegCPUData #( 16 ) U_0_032( CPU_rd_dout_h , 7'd032, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+ RegCPUData #( 1 ) U_0_033( Line_loop_en , 7'd033, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] );
+ RegCPUData #( 3 ) U_0_034( Speed , 7'd034, 3'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[2:0] );
+
+ // New registers for controlling the MDIO interface
+ RegCPUData #( 9 ) U_0_035( MIIMODER , 7'd035, 9'h064, RST_I, CLK_I, Wr, ADR_I, DAT_I[8:0] );
+ // Reg #36 is MIICOMMAND - implemented separately below
+ RegCPUData #( 13 ) U_0_037( MIIADDRESS , 7'd037, 13'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[12:0] );
+ RegCPUData #( 16 ) U_0_038( MIITX_DATA , 7'd038, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] );
+
+ // Asserted in first clock of 2-cycle access, negated otherwise
+ wire Access = ~ACK_O & STB_I & CYC_I;
+
+ // Asserted in first clock of 2-cycle write access, negated otherwise
+ assign Wr = Access & WE_I;
+
+ // MIICOMMAND register - needs special treatment because of auto-resetting bits
+ always @ ( posedge RST_I or posedge CLK_I )
+ if ( RST_I )
+ MIICOMMAND <= 0;
+ else
+ begin
+ if ( Wr & ( ADR_I == 7'd036 ) )
+ // Write access
+ MIICOMMAND <= DAT_I;
+ else
+ begin
+ if ( WCtrlDataStart )
+ MIICOMMAND[2] <= 0;
+ if ( RStatStart )
+ MIICOMMAND[1] <= 0;
+ end
+ end
+
+ // MIIRX_DATA register
+ always @ ( posedge RST_I or posedge CLK_I )
+ if ( RST_I )
+ MIIRX_DATA <= 0;
+ else
+ if ( UpdateMIIRX_DATAReg )
+ MIIRX_DATA <= Prsd;
+
+ // ACK_O is asserted in second clock of 2-cycle access, negated otherwise
+ always @ ( posedge RST_I or posedge CLK_I )
+ if ( RST_I )
+ ACK_O <= 0;
+ else
+ ACK_O <= Access;
+
+ always @ ( posedge RST_I or posedge CLK_I )
+ if(RST_I)
+ DAT_O <= 0;
+ else
+ begin
+ DAT_O <=0;
+ if ( Access & ~WE_I )
+ casez ( ADR_I )
+ 7'd00: DAT_O <= Tx_Hwmark;
+ 7'd01: DAT_O <= Tx_Lwmark;
+ 7'd02: DAT_O <= pause_frame_send_en;
+ 7'd03: DAT_O <= pause_quanta_set;
+ 7'd04: DAT_O <= IFGset;
+ 7'd05: DAT_O <= FullDuplex;
+ 7'd06: DAT_O <= MaxRetry;
+ 7'd07: DAT_O <= MAC_tx_add_en;
+ 7'd08: DAT_O <= MAC_tx_add_prom_data;
+ 7'd09: DAT_O <= MAC_tx_add_prom_add;
+ 7'd10: DAT_O <= MAC_tx_add_prom_wr;
+ 7'd11: DAT_O <= tx_pause_en;
+ 7'd12: DAT_O <= fc_hwmark;
+ 7'd13: DAT_O <= fc_lwmark;
+ 7'd14: DAT_O <= MAC_rx_add_chk_en;
+ 7'd15: DAT_O <= MAC_rx_add_prom_data;
+ 7'd16: DAT_O <= MAC_rx_add_prom_add;
+ 7'd17: DAT_O <= MAC_rx_add_prom_wr;
+ 7'd18: DAT_O <= broadcast_filter_en;
+ 7'd19: DAT_O <= broadcast_bucket_depth;
+ 7'd20: DAT_O <= broadcast_bucket_interval;
+ 7'd21: DAT_O <= RX_APPEND_CRC;
+ 7'd22: DAT_O <= Rx_Hwmark;
+ 7'd23: DAT_O <= Rx_Lwmark;
+ 7'd24: DAT_O <= CRC_chk_en;
+ 7'd25: DAT_O <= RX_IFG_SET;
+ 7'd26: DAT_O <= RX_MAX_LENGTH;
+ 7'd27: DAT_O <= RX_MIN_LENGTH;
+ 7'd28: DAT_O <= CPU_rd_addr;
+ 7'd29: DAT_O <= CPU_rd_apply;
+ 7'd30: DAT_O <= CPU_rd_grant;
+ 7'd31: DAT_O <= CPU_rd_dout;
+ //7'd32: DAT_O <= CPU_rd_dout[31:16];
+ 7'd33: DAT_O <= Line_loop_en;
+ 7'd34: DAT_O <= Speed;
+
+ // New registers for controlling MII interface
+ 7'd35: DAT_O <= MIIMODER;
+ 7'd36: DAT_O <= MIICOMMAND;
+ 7'd37: DAT_O <= MIIADDRESS;
+ 7'd38: DAT_O <= MIITX_DATA;
+ 7'd39: DAT_O <= MIIRX_DATA;
+ 7'd40: DAT_O <= MIISTATUS;
+ endcase
+ end
+
+endmodule
+
+module RegCPUData(
+ RegOut,
+ RegAddr,
+ RegInit,
+
+ Reset,
+ Clk,
+ Wr,
+ Addr,
+ WrData
+);
+
+ parameter WIDTH = 16;
+
+ output reg [WIDTH-1:0] RegOut;
+ input [6:0] RegAddr;
+ input [WIDTH-1:0] RegInit;
+
+ input Reset;
+ input Clk;
+ input Wr;
+ input [6:0] Addr;
+ input [WIDTH-1:0] WrData;
+
+ always @( posedge Reset or posedge Clk )
+ if ( Reset )
+ RegOut <= RegInit;
+ else
+ if ( Wr && ( Addr == RegAddr ) )
+ RegOut <= WrData;
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/TECH/eth_clk_div2.v b/usrp2/fpga/eth/rtl/verilog/TECH/eth_clk_div2.v new file mode 100644 index 000000000..994907d44 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/TECH/eth_clk_div2.v @@ -0,0 +1,71 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// eth_clk_div2.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: CLK_DIV2.v,v $
+// Revision 1.3 2006/01/19 14:07:56 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:20 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+
+//////////////////////////////////////////////////////////////////////
+// This file can only used for simulation .
+// You need to replace it with your own element according to technology
+//////////////////////////////////////////////////////////////////////
+
+module eth_clk_div2 (
+ input Reset,
+ input IN,
+ output reg OUT
+);
+
+always @ (posedge IN or posedge Reset)
+ if (Reset)
+ OUT <= 0;
+ else
+ OUT <= ~OUT;
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/TECH/eth_clk_switch.v b/usrp2/fpga/eth/rtl/verilog/TECH/eth_clk_switch.v new file mode 100644 index 000000000..c5375743f --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/TECH/eth_clk_switch.v @@ -0,0 +1,81 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// eth_clk_switch.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
+//// ////
+//// Author(s): ////
+//// - Jon Gao (gaojon@yahoo.com) ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: CLK_SWITCH.v,v $
+// Revision 1.3 2006/01/19 14:07:56 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:20 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+
+`include "header.vh"
+
+//////////////////////////////////////////////////////////////////////
+// This file can only used for simulation .
+// You need to replace it with your own element according to technology
+//////////////////////////////////////////////////////////////////////
+module eth_clk_switch (
+ input IN_0,
+ input IN_1,
+ input SW,
+ output OUT
+);
+
+`ifdef MAC_TARGET_XILINX
+
+ BUFGMUX U_BUFGMUX (
+ .O ( OUT ),
+ .I0( IN_0 ),
+ .I1( IN_1 ),
+ .S ( SW )
+ );
+
+`else
+
+ assign OUT = SW ? IN_1 : IN_0;
+
+`endif
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/TECH/xilinx/BUFGMUX.v b/usrp2/fpga/eth/rtl/verilog/TECH/xilinx/BUFGMUX.v new file mode 100644 index 000000000..f5bb4a74a --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/TECH/xilinx/BUFGMUX.v @@ -0,0 +1,64 @@ +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/BUFGMUX.v,v 1.9.34.2 2005/10/21 20:45:30 wloo Exp $ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995/2004 Xilinx, Inc. +// All Right Reserved. +/////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor : Xilinx +// \ \ \/ Version : 7.1i (H.19) +// \ \ Description : Xilinx Functional Simulation Library Component +// / / Global Clock Mux Buffer with Output State 0 +// /___/ /\ Filename : BUFGMUX.v +// \ \ / \ Timestamp : Thu Mar 25 16:42:14 PST 2004 +// \___\/\___\ +// +// Revision: +// 03/23/04 - Initial version. + +`timescale 100 ps / 10 ps + +module BUFGMUX (O, I0, I1, S); + + output O; + + input I0, I1, S; + + reg q0, q1; + reg q0_enable, q1_enable; + + tri0 GSR = glbl.GSR; + + bufif1 B0 (O, I0, q0); + bufif1 B1 (O, I1, q1); + pulldown P1 (O); + + always @(GSR or I0 or S or q0_enable) + if (GSR) + q0 <= 1; + else if (!I0) + q0 <= !S && q0_enable; + + always @(GSR or I1 or S or q1_enable) + if (GSR) + q1 <= 0; + else if (!I1) + q1 <= S && q1_enable; + + always @(GSR or q1 or I0) + if (GSR) + q0_enable <= 1; + else if (q1) + q0_enable <= 0; + else if (I0) + q0_enable <= !q1; + + always @(GSR or q0 or I1) + if (GSR) + q1_enable <= 0; + else if (q0) + q1_enable <= 0; + else if (I1) + q1_enable <= !q0; + +endmodule diff --git a/usrp2/fpga/eth/rtl/verilog/TECH/xilinx/RAMB16_S36_S36.v b/usrp2/fpga/eth/rtl/verilog/TECH/xilinx/RAMB16_S36_S36.v new file mode 100644 index 000000000..80545a9b8 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/TECH/xilinx/RAMB16_S36_S36.v @@ -0,0 +1,2204 @@ +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S36_S36.v,v 1.9 2005/03/14 22:54:41 wloo Exp $ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995/2005 Xilinx, Inc. +// All Right Reserved. +/////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor : Xilinx +// \ \ \/ Version : 8.1i (I.13) +// \ \ Description : Xilinx Functional Simulation Library Component +// / / 16K-Bit Data and 2K-Bit Parity Dual Port Block RAM +// /___/ /\ Filename : RAMB16_S36_S36.v +// \ \ / \ Timestamp : Thu Mar 10 16:43:36 PST 2005 +// \___\/\___\ +// +// Revision: +// 03/23/04 - Initial version. +// End Revision + +`ifdef legacy_model + +`timescale 1 ps / 1 ps + +module RAMB16_S36_S36 (DOA, DOB, DOPA, DOPB, ADDRA, ADDRB, CLKA, CLKB, DIA, DIB, DIPA, DIPB, ENA, ENB, SSRA, SSRB, WEA, WEB); + + parameter INIT_A = 36'h0; + parameter INIT_B = 36'h0; + parameter SRVAL_A = 36'h0; + parameter SRVAL_B = 36'h0; + parameter WRITE_MODE_A = "WRITE_FIRST"; + parameter WRITE_MODE_B = "WRITE_FIRST"; + parameter SIM_COLLISION_CHECK = "ALL"; + localparam SETUP_ALL = 1000; + localparam SETUP_READ_FIRST = 3000; + + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + output [31:0] DOA; + output [3:0] DOPA; + reg [31:0] doa_out; + reg [3:0] dopa_out; + wire doa_out0, doa_out1, doa_out2, doa_out3, doa_out4, doa_out5, doa_out6, doa_out7, doa_out8, doa_out9, doa_out10, doa_out11, doa_out12, doa_out13, doa_out14, doa_out15, doa_out16, doa_out17, doa_out18, doa_out19, doa_out20, doa_out21, doa_out22, doa_out23, doa_out24, doa_out25, doa_out26, doa_out27, doa_out28, doa_out29, doa_out30, doa_out31; + wire dopa0_out, dopa1_out, dopa2_out, dopa3_out; + + input [8:0] ADDRA; + input [31:0] DIA; + input [3:0] DIPA; + input ENA, CLKA, WEA, SSRA; + + output [31:0] DOB; + output [3:0] DOPB; + reg [31:0] dob_out; + reg [3:0] dopb_out; + wire dob_out0, dob_out1, dob_out2, dob_out3, dob_out4, dob_out5, dob_out6, dob_out7, dob_out8, dob_out9, dob_out10, dob_out11, dob_out12, dob_out13, dob_out14, dob_out15, dob_out16, dob_out17, dob_out18, dob_out19, dob_out20, dob_out21, dob_out22, dob_out23, dob_out24, dob_out25, dob_out26, dob_out27, dob_out28, dob_out29, dob_out30, dob_out31; + wire dopb0_out, dopb1_out, dopb2_out, dopb3_out; + + input [8:0] ADDRB; + input [31:0] DIB; + input [3:0] DIPB; + input ENB, CLKB, WEB, SSRB; + + reg [18431:0] mem; + reg [8:0] count; + reg [1:0] wr_mode_a, wr_mode_b; + + reg [5:0] dmi, dbi; + reg [5:0] pmi, pbi; + + wire [8:0] addra_int; + reg [8:0] addra_reg; + wire [31:0] dia_int; + wire [3:0] dipa_int; + wire ena_int, clka_int, wea_int, ssra_int; + reg ena_reg, wea_reg, ssra_reg; + wire [8:0] addrb_int; + reg [8:0] addrb_reg; + wire [31:0] dib_int; + wire [3:0] dipb_int; + wire enb_int, clkb_int, web_int, ssrb_int; + reg display_flag; + reg enb_reg, web_reg, ssrb_reg; + + time time_clka, time_clkb; + time time_clka_clkb; + time time_clkb_clka; + + reg setup_all_a_b; + reg setup_all_b_a; + reg setup_zero; + reg setup_rf_a_b; + reg setup_rf_b_a; + reg [1:0] data_collision, data_collision_a_b, data_collision_b_a; + reg memory_collision, memory_collision_a_b, memory_collision_b_a; + reg address_collision, address_collision_a_b, address_collision_b_a; + reg change_clka; + reg change_clkb; + + wire [14:0] data_addra_int; + wire [14:0] data_addra_reg; + wire [14:0] data_addrb_int; + wire [14:0] data_addrb_reg; + wire [15:0] parity_addra_int; + wire [15:0] parity_addra_reg; + wire [15:0] parity_addrb_int; + wire [15:0] parity_addrb_reg; + + tri0 GSR = glbl.GSR; + + always @(GSR) + if (GSR) begin + assign doa_out = INIT_A[31:0]; + assign dopa_out = INIT_A[35:32]; + assign dob_out = INIT_B[31:0]; + assign dopb_out = INIT_B[35:32]; + end + else begin + deassign doa_out; + deassign dopa_out; + deassign dob_out; + deassign dopb_out; + end + + buf b_doa_out0 (doa_out0, doa_out[0]); + buf b_doa_out1 (doa_out1, doa_out[1]); + buf b_doa_out2 (doa_out2, doa_out[2]); + buf b_doa_out3 (doa_out3, doa_out[3]); + buf b_doa_out4 (doa_out4, doa_out[4]); + buf b_doa_out5 (doa_out5, doa_out[5]); + buf b_doa_out6 (doa_out6, doa_out[6]); + buf b_doa_out7 (doa_out7, doa_out[7]); + buf b_doa_out8 (doa_out8, doa_out[8]); + buf b_doa_out9 (doa_out9, doa_out[9]); + buf b_doa_out10 (doa_out10, doa_out[10]); + buf b_doa_out11 (doa_out11, doa_out[11]); + buf b_doa_out12 (doa_out12, doa_out[12]); + buf b_doa_out13 (doa_out13, doa_out[13]); + buf b_doa_out14 (doa_out14, doa_out[14]); + buf b_doa_out15 (doa_out15, doa_out[15]); + buf b_doa_out16 (doa_out16, doa_out[16]); + buf b_doa_out17 (doa_out17, doa_out[17]); + buf b_doa_out18 (doa_out18, doa_out[18]); + buf b_doa_out19 (doa_out19, doa_out[19]); + buf b_doa_out20 (doa_out20, doa_out[20]); + buf b_doa_out21 (doa_out21, doa_out[21]); + buf b_doa_out22 (doa_out22, doa_out[22]); + buf b_doa_out23 (doa_out23, doa_out[23]); + buf b_doa_out24 (doa_out24, doa_out[24]); + buf b_doa_out25 (doa_out25, doa_out[25]); + buf b_doa_out26 (doa_out26, doa_out[26]); + buf b_doa_out27 (doa_out27, doa_out[27]); + buf b_doa_out28 (doa_out28, doa_out[28]); + buf b_doa_out29 (doa_out29, doa_out[29]); + buf b_doa_out30 (doa_out30, doa_out[30]); + buf b_doa_out31 (doa_out31, doa_out[31]); + buf b_dopa_out0 (dopa_out0, dopa_out[0]); + buf b_dopa_out1 (dopa_out1, dopa_out[1]); + buf b_dopa_out2 (dopa_out2, dopa_out[2]); + buf b_dopa_out3 (dopa_out3, dopa_out[3]); + buf b_dob_out0 (dob_out0, dob_out[0]); + buf b_dob_out1 (dob_out1, dob_out[1]); + buf b_dob_out2 (dob_out2, dob_out[2]); + buf b_dob_out3 (dob_out3, dob_out[3]); + buf b_dob_out4 (dob_out4, dob_out[4]); + buf b_dob_out5 (dob_out5, dob_out[5]); + buf b_dob_out6 (dob_out6, dob_out[6]); + buf b_dob_out7 (dob_out7, dob_out[7]); + buf b_dob_out8 (dob_out8, dob_out[8]); + buf b_dob_out9 (dob_out9, dob_out[9]); + buf b_dob_out10 (dob_out10, dob_out[10]); + buf b_dob_out11 (dob_out11, dob_out[11]); + buf b_dob_out12 (dob_out12, dob_out[12]); + buf b_dob_out13 (dob_out13, dob_out[13]); + buf b_dob_out14 (dob_out14, dob_out[14]); + buf b_dob_out15 (dob_out15, dob_out[15]); + buf b_dob_out16 (dob_out16, dob_out[16]); + buf b_dob_out17 (dob_out17, dob_out[17]); + buf b_dob_out18 (dob_out18, dob_out[18]); + buf b_dob_out19 (dob_out19, dob_out[19]); + buf b_dob_out20 (dob_out20, dob_out[20]); + buf b_dob_out21 (dob_out21, dob_out[21]); + buf b_dob_out22 (dob_out22, dob_out[22]); + buf b_dob_out23 (dob_out23, dob_out[23]); + buf b_dob_out24 (dob_out24, dob_out[24]); + buf b_dob_out25 (dob_out25, dob_out[25]); + buf b_dob_out26 (dob_out26, dob_out[26]); + buf b_dob_out27 (dob_out27, dob_out[27]); + buf b_dob_out28 (dob_out28, dob_out[28]); + buf b_dob_out29 (dob_out29, dob_out[29]); + buf b_dob_out30 (dob_out30, dob_out[30]); + buf b_dob_out31 (dob_out31, dob_out[31]); + buf b_dopb_out0 (dopb_out0, dopb_out[0]); + buf b_dopb_out1 (dopb_out1, dopb_out[1]); + buf b_dopb_out2 (dopb_out2, dopb_out[2]); + buf b_dopb_out3 (dopb_out3, dopb_out[3]); + + buf b_doa0 (DOA[0], doa_out0); + buf b_doa1 (DOA[1], doa_out1); + buf b_doa2 (DOA[2], doa_out2); + buf b_doa3 (DOA[3], doa_out3); + buf b_doa4 (DOA[4], doa_out4); + buf b_doa5 (DOA[5], doa_out5); + buf b_doa6 (DOA[6], doa_out6); + buf b_doa7 (DOA[7], doa_out7); + buf b_doa8 (DOA[8], doa_out8); + buf b_doa9 (DOA[9], doa_out9); + buf b_doa10 (DOA[10], doa_out10); + buf b_doa11 (DOA[11], doa_out11); + buf b_doa12 (DOA[12], doa_out12); + buf b_doa13 (DOA[13], doa_out13); + buf b_doa14 (DOA[14], doa_out14); + buf b_doa15 (DOA[15], doa_out15); + buf b_doa16 (DOA[16], doa_out16); + buf b_doa17 (DOA[17], doa_out17); + buf b_doa18 (DOA[18], doa_out18); + buf b_doa19 (DOA[19], doa_out19); + buf b_doa20 (DOA[20], doa_out20); + buf b_doa21 (DOA[21], doa_out21); + buf b_doa22 (DOA[22], doa_out22); + buf b_doa23 (DOA[23], doa_out23); + buf b_doa24 (DOA[24], doa_out24); + buf b_doa25 (DOA[25], doa_out25); + buf b_doa26 (DOA[26], doa_out26); + buf b_doa27 (DOA[27], doa_out27); + buf b_doa28 (DOA[28], doa_out28); + buf b_doa29 (DOA[29], doa_out29); + buf b_doa30 (DOA[30], doa_out30); + buf b_doa31 (DOA[31], doa_out31); + buf b_dopa0 (DOPA[0], dopa_out0); + buf b_dopa1 (DOPA[1], dopa_out1); + buf b_dopa2 (DOPA[2], dopa_out2); + buf b_dopa3 (DOPA[3], dopa_out3); + buf b_dob0 (DOB[0], dob_out0); + buf b_dob1 (DOB[1], dob_out1); + buf b_dob2 (DOB[2], dob_out2); + buf b_dob3 (DOB[3], dob_out3); + buf b_dob4 (DOB[4], dob_out4); + buf b_dob5 (DOB[5], dob_out5); + buf b_dob6 (DOB[6], dob_out6); + buf b_dob7 (DOB[7], dob_out7); + buf b_dob8 (DOB[8], dob_out8); + buf b_dob9 (DOB[9], dob_out9); + buf b_dob10 (DOB[10], dob_out10); + buf b_dob11 (DOB[11], dob_out11); + buf b_dob12 (DOB[12], dob_out12); + buf b_dob13 (DOB[13], dob_out13); + buf b_dob14 (DOB[14], dob_out14); + buf b_dob15 (DOB[15], dob_out15); + buf b_dob16 (DOB[16], dob_out16); + buf b_dob17 (DOB[17], dob_out17); + buf b_dob18 (DOB[18], dob_out18); + buf b_dob19 (DOB[19], dob_out19); + buf b_dob20 (DOB[20], dob_out20); + buf b_dob21 (DOB[21], dob_out21); + buf b_dob22 (DOB[22], dob_out22); + buf b_dob23 (DOB[23], dob_out23); + buf b_dob24 (DOB[24], dob_out24); + buf b_dob25 (DOB[25], dob_out25); + buf b_dob26 (DOB[26], dob_out26); + buf b_dob27 (DOB[27], dob_out27); + buf b_dob28 (DOB[28], dob_out28); + buf b_dob29 (DOB[29], dob_out29); + buf b_dob30 (DOB[30], dob_out30); + buf b_dob31 (DOB[31], dob_out31); + buf b_dopb0 (DOPB[0], dopb_out0); + buf b_dopb1 (DOPB[1], dopb_out1); + buf b_dopb2 (DOPB[2], dopb_out2); + buf b_dopb3 (DOPB[3], dopb_out3); + + buf b_addra_0 (addra_int[0], ADDRA[0]); + buf b_addra_1 (addra_int[1], ADDRA[1]); + buf b_addra_2 (addra_int[2], ADDRA[2]); + buf b_addra_3 (addra_int[3], ADDRA[3]); + buf b_addra_4 (addra_int[4], ADDRA[4]); + buf b_addra_5 (addra_int[5], ADDRA[5]); + buf b_addra_6 (addra_int[6], ADDRA[6]); + buf b_addra_7 (addra_int[7], ADDRA[7]); + buf b_addra_8 (addra_int[8], ADDRA[8]); + buf b_dia_0 (dia_int[0], DIA[0]); + buf b_dia_1 (dia_int[1], DIA[1]); + buf b_dia_2 (dia_int[2], DIA[2]); + buf b_dia_3 (dia_int[3], DIA[3]); + buf b_dia_4 (dia_int[4], DIA[4]); + buf b_dia_5 (dia_int[5], DIA[5]); + buf b_dia_6 (dia_int[6], DIA[6]); + buf b_dia_7 (dia_int[7], DIA[7]); + buf b_dia_8 (dia_int[8], DIA[8]); + buf b_dia_9 (dia_int[9], DIA[9]); + buf b_dia_10 (dia_int[10], DIA[10]); + buf b_dia_11 (dia_int[11], DIA[11]); + buf b_dia_12 (dia_int[12], DIA[12]); + buf b_dia_13 (dia_int[13], DIA[13]); + buf b_dia_14 (dia_int[14], DIA[14]); + buf b_dia_15 (dia_int[15], DIA[15]); + buf b_dia_16 (dia_int[16], DIA[16]); + buf b_dia_17 (dia_int[17], DIA[17]); + buf b_dia_18 (dia_int[18], DIA[18]); + buf b_dia_19 (dia_int[19], DIA[19]); + buf b_dia_20 (dia_int[20], DIA[20]); + buf b_dia_21 (dia_int[21], DIA[21]); + buf b_dia_22 (dia_int[22], DIA[22]); + buf b_dia_23 (dia_int[23], DIA[23]); + buf b_dia_24 (dia_int[24], DIA[24]); + buf b_dia_25 (dia_int[25], DIA[25]); + buf b_dia_26 (dia_int[26], DIA[26]); + buf b_dia_27 (dia_int[27], DIA[27]); + buf b_dia_28 (dia_int[28], DIA[28]); + buf b_dia_29 (dia_int[29], DIA[29]); + buf b_dia_30 (dia_int[30], DIA[30]); + buf b_dia_31 (dia_int[31], DIA[31]); + buf b_dipa_0 (dipa_int[0], DIPA[0]); + buf b_dipa_1 (dipa_int[1], DIPA[1]); + buf b_dipa_2 (dipa_int[2], DIPA[2]); + buf b_dipa_3 (dipa_int[3], DIPA[3]); + buf b_ena (ena_int, ENA); + buf b_clka (clka_int, CLKA); + buf b_ssra (ssra_int, SSRA); + buf b_wea (wea_int, WEA); + buf b_addrb_0 (addrb_int[0], ADDRB[0]); + buf b_addrb_1 (addrb_int[1], ADDRB[1]); + buf b_addrb_2 (addrb_int[2], ADDRB[2]); + buf b_addrb_3 (addrb_int[3], ADDRB[3]); + buf b_addrb_4 (addrb_int[4], ADDRB[4]); + buf b_addrb_5 (addrb_int[5], ADDRB[5]); + buf b_addrb_6 (addrb_int[6], ADDRB[6]); + buf b_addrb_7 (addrb_int[7], ADDRB[7]); + buf b_addrb_8 (addrb_int[8], ADDRB[8]); + buf b_dib_0 (dib_int[0], DIB[0]); + buf b_dib_1 (dib_int[1], DIB[1]); + buf b_dib_2 (dib_int[2], DIB[2]); + buf b_dib_3 (dib_int[3], DIB[3]); + buf b_dib_4 (dib_int[4], DIB[4]); + buf b_dib_5 (dib_int[5], DIB[5]); + buf b_dib_6 (dib_int[6], DIB[6]); + buf b_dib_7 (dib_int[7], DIB[7]); + buf b_dib_8 (dib_int[8], DIB[8]); + buf b_dib_9 (dib_int[9], DIB[9]); + buf b_dib_10 (dib_int[10], DIB[10]); + buf b_dib_11 (dib_int[11], DIB[11]); + buf b_dib_12 (dib_int[12], DIB[12]); + buf b_dib_13 (dib_int[13], DIB[13]); + buf b_dib_14 (dib_int[14], DIB[14]); + buf b_dib_15 (dib_int[15], DIB[15]); + buf b_dib_16 (dib_int[16], DIB[16]); + buf b_dib_17 (dib_int[17], DIB[17]); + buf b_dib_18 (dib_int[18], DIB[18]); + buf b_dib_19 (dib_int[19], DIB[19]); + buf b_dib_20 (dib_int[20], DIB[20]); + buf b_dib_21 (dib_int[21], DIB[21]); + buf b_dib_22 (dib_int[22], DIB[22]); + buf b_dib_23 (dib_int[23], DIB[23]); + buf b_dib_24 (dib_int[24], DIB[24]); + buf b_dib_25 (dib_int[25], DIB[25]); + buf b_dib_26 (dib_int[26], DIB[26]); + buf b_dib_27 (dib_int[27], DIB[27]); + buf b_dib_28 (dib_int[28], DIB[28]); + buf b_dib_29 (dib_int[29], DIB[29]); + buf b_dib_30 (dib_int[30], DIB[30]); + buf b_dib_31 (dib_int[31], DIB[31]); + buf b_dipb_0 (dipb_int[0], DIPB[0]); + buf b_dipb_1 (dipb_int[1], DIPB[1]); + buf b_dipb_2 (dipb_int[2], DIPB[2]); + buf b_dipb_3 (dipb_int[3], DIPB[3]); + buf b_enb (enb_int, ENB); + buf b_clkb (clkb_int, CLKB); + buf b_ssrb (ssrb_int, SSRB); + buf b_web (web_int, WEB); + + initial begin + for (count = 0; count < 256; count = count + 1) begin + mem[count] <= INIT_00[count]; + mem[256 * 1 + count] <= INIT_01[count]; + mem[256 * 2 + count] <= INIT_02[count]; + mem[256 * 3 + count] <= INIT_03[count]; + mem[256 * 4 + count] <= INIT_04[count]; + mem[256 * 5 + count] <= INIT_05[count]; + mem[256 * 6 + count] <= INIT_06[count]; + mem[256 * 7 + count] <= INIT_07[count]; + mem[256 * 8 + count] <= INIT_08[count]; + mem[256 * 9 + count] <= INIT_09[count]; + mem[256 * 10 + count] <= INIT_0A[count]; + mem[256 * 11 + count] <= INIT_0B[count]; + mem[256 * 12 + count] <= INIT_0C[count]; + mem[256 * 13 + count] <= INIT_0D[count]; + mem[256 * 14 + count] <= INIT_0E[count]; + mem[256 * 15 + count] <= INIT_0F[count]; + mem[256 * 16 + count] <= INIT_10[count]; + mem[256 * 17 + count] <= INIT_11[count]; + mem[256 * 18 + count] <= INIT_12[count]; + mem[256 * 19 + count] <= INIT_13[count]; + mem[256 * 20 + count] <= INIT_14[count]; + mem[256 * 21 + count] <= INIT_15[count]; + mem[256 * 22 + count] <= INIT_16[count]; + mem[256 * 23 + count] <= INIT_17[count]; + mem[256 * 24 + count] <= INIT_18[count]; + mem[256 * 25 + count] <= INIT_19[count]; + mem[256 * 26 + count] <= INIT_1A[count]; + mem[256 * 27 + count] <= INIT_1B[count]; + mem[256 * 28 + count] <= INIT_1C[count]; + mem[256 * 29 + count] <= INIT_1D[count]; + mem[256 * 30 + count] <= INIT_1E[count]; + mem[256 * 31 + count] <= INIT_1F[count]; + mem[256 * 32 + count] <= INIT_20[count]; + mem[256 * 33 + count] <= INIT_21[count]; + mem[256 * 34 + count] <= INIT_22[count]; + mem[256 * 35 + count] <= INIT_23[count]; + mem[256 * 36 + count] <= INIT_24[count]; + mem[256 * 37 + count] <= INIT_25[count]; + mem[256 * 38 + count] <= INIT_26[count]; + mem[256 * 39 + count] <= INIT_27[count]; + mem[256 * 40 + count] <= INIT_28[count]; + mem[256 * 41 + count] <= INIT_29[count]; + mem[256 * 42 + count] <= INIT_2A[count]; + mem[256 * 43 + count] <= INIT_2B[count]; + mem[256 * 44 + count] <= INIT_2C[count]; + mem[256 * 45 + count] <= INIT_2D[count]; + mem[256 * 46 + count] <= INIT_2E[count]; + mem[256 * 47 + count] <= INIT_2F[count]; + mem[256 * 48 + count] <= INIT_30[count]; + mem[256 * 49 + count] <= INIT_31[count]; + mem[256 * 50 + count] <= INIT_32[count]; + mem[256 * 51 + count] <= INIT_33[count]; + mem[256 * 52 + count] <= INIT_34[count]; + mem[256 * 53 + count] <= INIT_35[count]; + mem[256 * 54 + count] <= INIT_36[count]; + mem[256 * 55 + count] <= INIT_37[count]; + mem[256 * 56 + count] <= INIT_38[count]; + mem[256 * 57 + count] <= INIT_39[count]; + mem[256 * 58 + count] <= INIT_3A[count]; + mem[256 * 59 + count] <= INIT_3B[count]; + mem[256 * 60 + count] <= INIT_3C[count]; + mem[256 * 61 + count] <= INIT_3D[count]; + mem[256 * 62 + count] <= INIT_3E[count]; + mem[256 * 63 + count] <= INIT_3F[count]; + mem[256 * 64 + count] <= INITP_00[count]; + mem[256 * 65 + count] <= INITP_01[count]; + mem[256 * 66 + count] <= INITP_02[count]; + mem[256 * 67 + count] <= INITP_03[count]; + mem[256 * 68 + count] <= INITP_04[count]; + mem[256 * 69 + count] <= INITP_05[count]; + mem[256 * 70 + count] <= INITP_06[count]; + mem[256 * 71 + count] <= INITP_07[count]; + end + address_collision <= 0; + address_collision_a_b <= 0; + address_collision_b_a <= 0; + change_clka <= 0; + change_clkb <= 0; + data_collision <= 0; + data_collision_a_b <= 0; + data_collision_b_a <= 0; + memory_collision <= 0; + memory_collision_a_b <= 0; + memory_collision_b_a <= 0; + setup_all_a_b <= 0; + setup_all_b_a <= 0; + setup_zero <= 0; + setup_rf_a_b <= 0; + setup_rf_b_a <= 0; + end + + assign data_addra_int = addra_int * 32; + assign data_addra_reg = addra_reg * 32; + assign data_addrb_int = addrb_int * 32; + assign data_addrb_reg = addrb_reg * 32; + assign parity_addra_int = 16384 + addra_int * 4; + assign parity_addra_reg = 16384 + addra_reg * 4; + assign parity_addrb_int = 16384 + addrb_int * 4; + assign parity_addrb_reg = 16384 + addrb_reg * 4; + + + initial begin + + display_flag = 1; + + case (SIM_COLLISION_CHECK) + + "NONE" : begin + assign setup_all_a_b = 1'b0; + assign setup_all_b_a = 1'b0; + assign setup_zero = 1'b0; + assign setup_rf_a_b = 1'b0; + assign setup_rf_b_a = 1'b0; + assign display_flag = 0; + end + "WARNING_ONLY" : begin + assign data_collision = 2'b00; + assign data_collision_a_b = 2'b00; + assign data_collision_b_a = 2'b00; + assign memory_collision = 1'b0; + assign memory_collision_a_b = 1'b0; + assign memory_collision_b_a = 1'b0; + end + "GENERATE_X_ONLY" : begin + assign display_flag = 0; + end + "ALL" : ; + default : begin + $display("Attribute Syntax Error : The Attribute SIM_COLLISION_CHECK on RAMB16_S36_S36 instance %m is set to %s. Legal values for this attribute are ALL, NONE, WARNING_ONLY or GENERATE_X_ONLY.", SIM_COLLISION_CHECK); + $finish; + end + + endcase // case(SIM_COLLISION_CHECK) + + end // initial begin + + + always @(posedge clka_int) begin + time_clka = $time; + #0 time_clkb_clka = time_clka - time_clkb; + change_clka = ~change_clka; + end + + always @(posedge clkb_int) begin + time_clkb = $time; + #0 time_clka_clkb = time_clkb - time_clka; + change_clkb = ~change_clkb; + end + + always @(change_clkb) begin + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_ALL)) + setup_all_a_b = 1; + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_READ_FIRST)) + setup_rf_a_b = 1; + end + + always @(change_clka) begin + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_ALL)) + setup_all_b_a = 1; + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_READ_FIRST)) + setup_rf_b_a = 1; + end + + always @(change_clkb or change_clka) begin + if ((time_clkb_clka == 0) && (time_clka_clkb == 0)) + setup_zero = 1; + end + + always @(posedge setup_zero) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_int[14:5] == data_addrb_int[14:5])) + memory_collision <= 1; + end + + always @(posedge setup_all_a_b or posedge setup_rf_a_b) begin + if ((ena_reg == 1) && (wea_reg == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_reg[14:5] == data_addrb_int[14:5])) + memory_collision_a_b <= 1; + end + + always @(posedge setup_all_b_a or posedge setup_rf_b_a) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_reg == 1) && (web_reg == 1) && + (data_addra_int[14:5] == data_addrb_reg[14:5])) + memory_collision_b_a <= 1; + end + + always @(posedge setup_all_a_b) begin + if (data_addra_reg[14:5] == data_addrb_int[14:5]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) + 6'b000011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b010011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b010111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b011011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b100011 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_a_b <= 0; + end + + + always @(posedge setup_all_b_a) begin + if (data_addra_int[14:5] == data_addrb_reg[14:5]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) + 6'b000011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b000111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b001011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b010111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b011011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b001001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b011001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b101001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_b_a <= 0; + end + + + always @(posedge setup_zero) begin + if (data_addra_int[14:5] == data_addrb_int[14:5]) begin + if ((ena_int == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_int}) + 6'b000011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision <= 2'b01; display_wa_rb; end + endcase + end + end + setup_zero <= 0; + end + + task display_ra_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S36_S36:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port A while a write was requested to the same address on Port B. The write will be successful however the read value on Port A is unknown until the next CLKA cycle.", $time/1000.0, addra_int); + end + endtask + + task display_wa_rb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S36_S36:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port B while a write was requested to the same address on Port A. The write will be successful however the read value on Port B is unknown until the next CLKB cycle.", $time/1000.0, addrb_int); + end + endtask + + task display_wa_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S36_S36:%m at simulation time %.3f ns\nA write was requested to the same address simultaneously at both Port A and Port B of the RAM. The contents written to the RAM at address location %h (hex) of Port A and address location %h (hex) of Port B are unknown.", $time/1000.0, addra_int, addrb_int); + end + endtask + + + always @(posedge setup_rf_a_b) begin + if (data_addra_reg[14:5] == data_addrb_int[14:5]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) +// 6'b000011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b001011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b010011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b100011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b100111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b101011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b001001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b011001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b101001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b010010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b010110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b011010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b100010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_a_b <= 0; + end + + + always @(posedge setup_rf_b_a) begin + if (data_addra_int[14:5] == data_addrb_reg[14:5]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) +// 6'b000011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b000111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b001011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b010011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b010111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b011011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b100011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end +// 6'b101011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b001001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b011001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b101001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_b_a <= 0; + end + + + always @(posedge clka_int) begin + addra_reg <= addra_int; + ena_reg <= ena_int; + ssra_reg <= ssra_int; + wea_reg <= wea_int; + end + + always @(posedge clkb_int) begin + addrb_reg <= addrb_int; + enb_reg <= enb_int; + ssrb_reg <= ssrb_int; + web_reg <= web_int; + end + + // Data + always @(posedge memory_collision) begin + for (dmi = 0; dmi < 32; dmi = dmi + 1) begin + mem[data_addra_int + dmi] <= 1'bX; + end + memory_collision <= 0; + end + + always @(posedge memory_collision_a_b) begin + for (dmi = 0; dmi < 32; dmi = dmi + 1) begin + mem[data_addra_reg + dmi] <= 1'bX; + end + memory_collision_a_b <= 0; + end + + always @(posedge memory_collision_b_a) begin + for (dmi = 0; dmi < 32; dmi = dmi + 1) begin + mem[data_addra_int + dmi] <= 1'bX; + end + memory_collision_b_a <= 0; + end + + always @(posedge data_collision[1]) begin + if (ssra_int == 0) begin + doa_out <= 32'bX; + end + data_collision[1] <= 0; + end + + always @(posedge data_collision[0]) begin + if (ssrb_int == 0) begin + dob_out <= 32'bX; + end + data_collision[0] <= 0; + end + + always @(posedge data_collision_a_b[1]) begin + if (ssra_reg == 0) begin + doa_out <= 32'bX; + end + data_collision_a_b[1] <= 0; + end + + always @(posedge data_collision_a_b[0]) begin + if (ssrb_int == 0) begin + dob_out <= 32'bX; + end + data_collision_a_b[0] <= 0; + end + + always @(posedge data_collision_b_a[1]) begin + if (ssra_int == 0) begin + doa_out <= 32'bX; + end + data_collision_b_a[1] <= 0; + end + + always @(posedge data_collision_b_a[0]) begin + if (ssrb_reg == 0) begin + dob_out <= 32'bX; + end + data_collision_b_a[0] <= 0; + end + + + // Parity + always @(posedge memory_collision) begin + for (pmi = 0; pmi < 4; pmi = pmi + 1) begin + mem[parity_addra_int + pmi] <= 1'bX; + end + end + + always @(posedge memory_collision_a_b) begin + for (pmi = 0; pmi < 4; pmi = pmi + 1) begin + mem[parity_addra_reg + pmi] <= 1'bX; + end + end + + always @(posedge memory_collision_b_a) begin + for (pmi = 0; pmi < 4; pmi = pmi + 1) begin + mem[parity_addra_int + pmi] <= 1'bX; + end + end + + always @(posedge data_collision[1]) begin + if (ssra_int == 0) begin + dopa_out <= 4'bX; + end + end + + always @(posedge data_collision[0]) begin + if (ssrb_int == 0) begin + dopb_out <= 4'bX; + end + end + + always @(posedge data_collision_a_b[1]) begin + if (ssra_reg == 0) begin + dopa_out <= 4'bX; + end + end + + always @(posedge data_collision_a_b[0]) begin + if (ssrb_int == 0) begin + dopb_out <= 4'bX; + end + end + + always @(posedge data_collision_b_a[1]) begin + if (ssra_int == 0) begin + dopa_out <= 4'bX; + end + end + + always @(posedge data_collision_b_a[0]) begin + if (ssrb_reg == 0) begin + dopb_out <= 4'bX; + end + end + + + initial begin + case (WRITE_MODE_A) + "WRITE_FIRST" : wr_mode_a <= 2'b00; + "READ_FIRST" : wr_mode_a <= 2'b01; + "NO_CHANGE" : wr_mode_a <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_A on RAMB16_S36_S36 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_A); + $finish; + end + endcase + end + + initial begin + case (WRITE_MODE_B) + "WRITE_FIRST" : wr_mode_b <= 2'b00; + "READ_FIRST" : wr_mode_b <= 2'b01; + "NO_CHANGE" : wr_mode_b <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_B on RAMB16_S36_S36 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_B); + $finish; + end + endcase + end + + // Port A + always @(posedge clka_int) begin + if (ena_int == 1'b1) begin + if (ssra_int == 1'b1) begin + doa_out[0] <= SRVAL_A[0]; + doa_out[1] <= SRVAL_A[1]; + doa_out[2] <= SRVAL_A[2]; + doa_out[3] <= SRVAL_A[3]; + doa_out[4] <= SRVAL_A[4]; + doa_out[5] <= SRVAL_A[5]; + doa_out[6] <= SRVAL_A[6]; + doa_out[7] <= SRVAL_A[7]; + doa_out[8] <= SRVAL_A[8]; + doa_out[9] <= SRVAL_A[9]; + doa_out[10] <= SRVAL_A[10]; + doa_out[11] <= SRVAL_A[11]; + doa_out[12] <= SRVAL_A[12]; + doa_out[13] <= SRVAL_A[13]; + doa_out[14] <= SRVAL_A[14]; + doa_out[15] <= SRVAL_A[15]; + doa_out[16] <= SRVAL_A[16]; + doa_out[17] <= SRVAL_A[17]; + doa_out[18] <= SRVAL_A[18]; + doa_out[19] <= SRVAL_A[19]; + doa_out[20] <= SRVAL_A[20]; + doa_out[21] <= SRVAL_A[21]; + doa_out[22] <= SRVAL_A[22]; + doa_out[23] <= SRVAL_A[23]; + doa_out[24] <= SRVAL_A[24]; + doa_out[25] <= SRVAL_A[25]; + doa_out[26] <= SRVAL_A[26]; + doa_out[27] <= SRVAL_A[27]; + doa_out[28] <= SRVAL_A[28]; + doa_out[29] <= SRVAL_A[29]; + doa_out[30] <= SRVAL_A[30]; + doa_out[31] <= SRVAL_A[31]; + dopa_out[0] <= SRVAL_A[32]; + dopa_out[1] <= SRVAL_A[33]; + dopa_out[2] <= SRVAL_A[34]; + dopa_out[3] <= SRVAL_A[35]; + end + else begin + if (wea_int == 1'b1) begin + if (wr_mode_a == 2'b00) begin + doa_out <= dia_int; + dopa_out <= dipa_int; + end + else if (wr_mode_a == 2'b01) begin + doa_out[0] <= mem[data_addra_int + 0]; + doa_out[1] <= mem[data_addra_int + 1]; + doa_out[2] <= mem[data_addra_int + 2]; + doa_out[3] <= mem[data_addra_int + 3]; + doa_out[4] <= mem[data_addra_int + 4]; + doa_out[5] <= mem[data_addra_int + 5]; + doa_out[6] <= mem[data_addra_int + 6]; + doa_out[7] <= mem[data_addra_int + 7]; + doa_out[8] <= mem[data_addra_int + 8]; + doa_out[9] <= mem[data_addra_int + 9]; + doa_out[10] <= mem[data_addra_int + 10]; + doa_out[11] <= mem[data_addra_int + 11]; + doa_out[12] <= mem[data_addra_int + 12]; + doa_out[13] <= mem[data_addra_int + 13]; + doa_out[14] <= mem[data_addra_int + 14]; + doa_out[15] <= mem[data_addra_int + 15]; + doa_out[16] <= mem[data_addra_int + 16]; + doa_out[17] <= mem[data_addra_int + 17]; + doa_out[18] <= mem[data_addra_int + 18]; + doa_out[19] <= mem[data_addra_int + 19]; + doa_out[20] <= mem[data_addra_int + 20]; + doa_out[21] <= mem[data_addra_int + 21]; + doa_out[22] <= mem[data_addra_int + 22]; + doa_out[23] <= mem[data_addra_int + 23]; + doa_out[24] <= mem[data_addra_int + 24]; + doa_out[25] <= mem[data_addra_int + 25]; + doa_out[26] <= mem[data_addra_int + 26]; + doa_out[27] <= mem[data_addra_int + 27]; + doa_out[28] <= mem[data_addra_int + 28]; + doa_out[29] <= mem[data_addra_int + 29]; + doa_out[30] <= mem[data_addra_int + 30]; + doa_out[31] <= mem[data_addra_int + 31]; + dopa_out[0] <= mem[parity_addra_int + 0]; + dopa_out[1] <= mem[parity_addra_int + 1]; + dopa_out[2] <= mem[parity_addra_int + 2]; + dopa_out[3] <= mem[parity_addra_int + 3]; + end + end + else begin + doa_out[0] <= mem[data_addra_int + 0]; + doa_out[1] <= mem[data_addra_int + 1]; + doa_out[2] <= mem[data_addra_int + 2]; + doa_out[3] <= mem[data_addra_int + 3]; + doa_out[4] <= mem[data_addra_int + 4]; + doa_out[5] <= mem[data_addra_int + 5]; + doa_out[6] <= mem[data_addra_int + 6]; + doa_out[7] <= mem[data_addra_int + 7]; + doa_out[8] <= mem[data_addra_int + 8]; + doa_out[9] <= mem[data_addra_int + 9]; + doa_out[10] <= mem[data_addra_int + 10]; + doa_out[11] <= mem[data_addra_int + 11]; + doa_out[12] <= mem[data_addra_int + 12]; + doa_out[13] <= mem[data_addra_int + 13]; + doa_out[14] <= mem[data_addra_int + 14]; + doa_out[15] <= mem[data_addra_int + 15]; + doa_out[16] <= mem[data_addra_int + 16]; + doa_out[17] <= mem[data_addra_int + 17]; + doa_out[18] <= mem[data_addra_int + 18]; + doa_out[19] <= mem[data_addra_int + 19]; + doa_out[20] <= mem[data_addra_int + 20]; + doa_out[21] <= mem[data_addra_int + 21]; + doa_out[22] <= mem[data_addra_int + 22]; + doa_out[23] <= mem[data_addra_int + 23]; + doa_out[24] <= mem[data_addra_int + 24]; + doa_out[25] <= mem[data_addra_int + 25]; + doa_out[26] <= mem[data_addra_int + 26]; + doa_out[27] <= mem[data_addra_int + 27]; + doa_out[28] <= mem[data_addra_int + 28]; + doa_out[29] <= mem[data_addra_int + 29]; + doa_out[30] <= mem[data_addra_int + 30]; + doa_out[31] <= mem[data_addra_int + 31]; + dopa_out[0] <= mem[parity_addra_int + 0]; + dopa_out[1] <= mem[parity_addra_int + 1]; + dopa_out[2] <= mem[parity_addra_int + 2]; + dopa_out[3] <= mem[parity_addra_int + 3]; + end + end + end + end + + always @(posedge clka_int) begin + if (ena_int == 1'b1 && wea_int == 1'b1) begin + mem[data_addra_int + 0] <= dia_int[0]; + mem[data_addra_int + 1] <= dia_int[1]; + mem[data_addra_int + 2] <= dia_int[2]; + mem[data_addra_int + 3] <= dia_int[3]; + mem[data_addra_int + 4] <= dia_int[4]; + mem[data_addra_int + 5] <= dia_int[5]; + mem[data_addra_int + 6] <= dia_int[6]; + mem[data_addra_int + 7] <= dia_int[7]; + mem[data_addra_int + 8] <= dia_int[8]; + mem[data_addra_int + 9] <= dia_int[9]; + mem[data_addra_int + 10] <= dia_int[10]; + mem[data_addra_int + 11] <= dia_int[11]; + mem[data_addra_int + 12] <= dia_int[12]; + mem[data_addra_int + 13] <= dia_int[13]; + mem[data_addra_int + 14] <= dia_int[14]; + mem[data_addra_int + 15] <= dia_int[15]; + mem[data_addra_int + 16] <= dia_int[16]; + mem[data_addra_int + 17] <= dia_int[17]; + mem[data_addra_int + 18] <= dia_int[18]; + mem[data_addra_int + 19] <= dia_int[19]; + mem[data_addra_int + 20] <= dia_int[20]; + mem[data_addra_int + 21] <= dia_int[21]; + mem[data_addra_int + 22] <= dia_int[22]; + mem[data_addra_int + 23] <= dia_int[23]; + mem[data_addra_int + 24] <= dia_int[24]; + mem[data_addra_int + 25] <= dia_int[25]; + mem[data_addra_int + 26] <= dia_int[26]; + mem[data_addra_int + 27] <= dia_int[27]; + mem[data_addra_int + 28] <= dia_int[28]; + mem[data_addra_int + 29] <= dia_int[29]; + mem[data_addra_int + 30] <= dia_int[30]; + mem[data_addra_int + 31] <= dia_int[31]; + mem[parity_addra_int + 0] <= dipa_int[0]; + mem[parity_addra_int + 1] <= dipa_int[1]; + mem[parity_addra_int + 2] <= dipa_int[2]; + mem[parity_addra_int + 3] <= dipa_int[3]; + end + end + + // Port B + always @(posedge clkb_int) begin + if (enb_int == 1'b1) begin + if (ssrb_int == 1'b1) begin + dob_out[0] <= SRVAL_B[0]; + dob_out[1] <= SRVAL_B[1]; + dob_out[2] <= SRVAL_B[2]; + dob_out[3] <= SRVAL_B[3]; + dob_out[4] <= SRVAL_B[4]; + dob_out[5] <= SRVAL_B[5]; + dob_out[6] <= SRVAL_B[6]; + dob_out[7] <= SRVAL_B[7]; + dob_out[8] <= SRVAL_B[8]; + dob_out[9] <= SRVAL_B[9]; + dob_out[10] <= SRVAL_B[10]; + dob_out[11] <= SRVAL_B[11]; + dob_out[12] <= SRVAL_B[12]; + dob_out[13] <= SRVAL_B[13]; + dob_out[14] <= SRVAL_B[14]; + dob_out[15] <= SRVAL_B[15]; + dob_out[16] <= SRVAL_B[16]; + dob_out[17] <= SRVAL_B[17]; + dob_out[18] <= SRVAL_B[18]; + dob_out[19] <= SRVAL_B[19]; + dob_out[20] <= SRVAL_B[20]; + dob_out[21] <= SRVAL_B[21]; + dob_out[22] <= SRVAL_B[22]; + dob_out[23] <= SRVAL_B[23]; + dob_out[24] <= SRVAL_B[24]; + dob_out[25] <= SRVAL_B[25]; + dob_out[26] <= SRVAL_B[26]; + dob_out[27] <= SRVAL_B[27]; + dob_out[28] <= SRVAL_B[28]; + dob_out[29] <= SRVAL_B[29]; + dob_out[30] <= SRVAL_B[30]; + dob_out[31] <= SRVAL_B[31]; + dopb_out[0] <= SRVAL_B[32]; + dopb_out[1] <= SRVAL_B[33]; + dopb_out[2] <= SRVAL_B[34]; + dopb_out[3] <= SRVAL_B[35]; + end + else begin + if (web_int == 1'b1) begin + if (wr_mode_b == 2'b00) begin + dob_out <= dib_int; + dopb_out <= dipb_int; + end + else if (wr_mode_b == 2'b01) begin + dob_out[0] <= mem[data_addrb_int + 0]; + dob_out[1] <= mem[data_addrb_int + 1]; + dob_out[2] <= mem[data_addrb_int + 2]; + dob_out[3] <= mem[data_addrb_int + 3]; + dob_out[4] <= mem[data_addrb_int + 4]; + dob_out[5] <= mem[data_addrb_int + 5]; + dob_out[6] <= mem[data_addrb_int + 6]; + dob_out[7] <= mem[data_addrb_int + 7]; + dob_out[8] <= mem[data_addrb_int + 8]; + dob_out[9] <= mem[data_addrb_int + 9]; + dob_out[10] <= mem[data_addrb_int + 10]; + dob_out[11] <= mem[data_addrb_int + 11]; + dob_out[12] <= mem[data_addrb_int + 12]; + dob_out[13] <= mem[data_addrb_int + 13]; + dob_out[14] <= mem[data_addrb_int + 14]; + dob_out[15] <= mem[data_addrb_int + 15]; + dob_out[16] <= mem[data_addrb_int + 16]; + dob_out[17] <= mem[data_addrb_int + 17]; + dob_out[18] <= mem[data_addrb_int + 18]; + dob_out[19] <= mem[data_addrb_int + 19]; + dob_out[20] <= mem[data_addrb_int + 20]; + dob_out[21] <= mem[data_addrb_int + 21]; + dob_out[22] <= mem[data_addrb_int + 22]; + dob_out[23] <= mem[data_addrb_int + 23]; + dob_out[24] <= mem[data_addrb_int + 24]; + dob_out[25] <= mem[data_addrb_int + 25]; + dob_out[26] <= mem[data_addrb_int + 26]; + dob_out[27] <= mem[data_addrb_int + 27]; + dob_out[28] <= mem[data_addrb_int + 28]; + dob_out[29] <= mem[data_addrb_int + 29]; + dob_out[30] <= mem[data_addrb_int + 30]; + dob_out[31] <= mem[data_addrb_int + 31]; + dopb_out[0] <= mem[parity_addrb_int + 0]; + dopb_out[1] <= mem[parity_addrb_int + 1]; + dopb_out[2] <= mem[parity_addrb_int + 2]; + dopb_out[3] <= mem[parity_addrb_int + 3]; + end + end + else begin + dob_out[0] <= mem[data_addrb_int + 0]; + dob_out[1] <= mem[data_addrb_int + 1]; + dob_out[2] <= mem[data_addrb_int + 2]; + dob_out[3] <= mem[data_addrb_int + 3]; + dob_out[4] <= mem[data_addrb_int + 4]; + dob_out[5] <= mem[data_addrb_int + 5]; + dob_out[6] <= mem[data_addrb_int + 6]; + dob_out[7] <= mem[data_addrb_int + 7]; + dob_out[8] <= mem[data_addrb_int + 8]; + dob_out[9] <= mem[data_addrb_int + 9]; + dob_out[10] <= mem[data_addrb_int + 10]; + dob_out[11] <= mem[data_addrb_int + 11]; + dob_out[12] <= mem[data_addrb_int + 12]; + dob_out[13] <= mem[data_addrb_int + 13]; + dob_out[14] <= mem[data_addrb_int + 14]; + dob_out[15] <= mem[data_addrb_int + 15]; + dob_out[16] <= mem[data_addrb_int + 16]; + dob_out[17] <= mem[data_addrb_int + 17]; + dob_out[18] <= mem[data_addrb_int + 18]; + dob_out[19] <= mem[data_addrb_int + 19]; + dob_out[20] <= mem[data_addrb_int + 20]; + dob_out[21] <= mem[data_addrb_int + 21]; + dob_out[22] <= mem[data_addrb_int + 22]; + dob_out[23] <= mem[data_addrb_int + 23]; + dob_out[24] <= mem[data_addrb_int + 24]; + dob_out[25] <= mem[data_addrb_int + 25]; + dob_out[26] <= mem[data_addrb_int + 26]; + dob_out[27] <= mem[data_addrb_int + 27]; + dob_out[28] <= mem[data_addrb_int + 28]; + dob_out[29] <= mem[data_addrb_int + 29]; + dob_out[30] <= mem[data_addrb_int + 30]; + dob_out[31] <= mem[data_addrb_int + 31]; + dopb_out[0] <= mem[parity_addrb_int + 0]; + dopb_out[1] <= mem[parity_addrb_int + 1]; + dopb_out[2] <= mem[parity_addrb_int + 2]; + dopb_out[3] <= mem[parity_addrb_int + 3]; + end + end + end + end + + always @(posedge clkb_int) begin + if (enb_int == 1'b1 && web_int == 1'b1) begin + mem[data_addrb_int + 0] <= dib_int[0]; + mem[data_addrb_int + 1] <= dib_int[1]; + mem[data_addrb_int + 2] <= dib_int[2]; + mem[data_addrb_int + 3] <= dib_int[3]; + mem[data_addrb_int + 4] <= dib_int[4]; + mem[data_addrb_int + 5] <= dib_int[5]; + mem[data_addrb_int + 6] <= dib_int[6]; + mem[data_addrb_int + 7] <= dib_int[7]; + mem[data_addrb_int + 8] <= dib_int[8]; + mem[data_addrb_int + 9] <= dib_int[9]; + mem[data_addrb_int + 10] <= dib_int[10]; + mem[data_addrb_int + 11] <= dib_int[11]; + mem[data_addrb_int + 12] <= dib_int[12]; + mem[data_addrb_int + 13] <= dib_int[13]; + mem[data_addrb_int + 14] <= dib_int[14]; + mem[data_addrb_int + 15] <= dib_int[15]; + mem[data_addrb_int + 16] <= dib_int[16]; + mem[data_addrb_int + 17] <= dib_int[17]; + mem[data_addrb_int + 18] <= dib_int[18]; + mem[data_addrb_int + 19] <= dib_int[19]; + mem[data_addrb_int + 20] <= dib_int[20]; + mem[data_addrb_int + 21] <= dib_int[21]; + mem[data_addrb_int + 22] <= dib_int[22]; + mem[data_addrb_int + 23] <= dib_int[23]; + mem[data_addrb_int + 24] <= dib_int[24]; + mem[data_addrb_int + 25] <= dib_int[25]; + mem[data_addrb_int + 26] <= dib_int[26]; + mem[data_addrb_int + 27] <= dib_int[27]; + mem[data_addrb_int + 28] <= dib_int[28]; + mem[data_addrb_int + 29] <= dib_int[29]; + mem[data_addrb_int + 30] <= dib_int[30]; + mem[data_addrb_int + 31] <= dib_int[31]; + mem[parity_addrb_int + 0] <= dipb_int[0]; + mem[parity_addrb_int + 1] <= dipb_int[1]; + mem[parity_addrb_int + 2] <= dipb_int[2]; + mem[parity_addrb_int + 3] <= dipb_int[3]; + end + end + + specify + (CLKA *> DOA) = (100, 100); + (CLKA *> DOPA) = (100, 100); + (CLKB *> DOB) = (100, 100); + (CLKB *> DOPB) = (100, 100); + endspecify + +endmodule + +`else + +// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S36_S36.v,v 1.9 2005/03/14 22:54:41 wloo Exp $ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995/2005 Xilinx, Inc. +// All Right Reserved. +/////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor : Xilinx +// \ \ \/ Version : 8.1i (I.13) +// \ \ Description : Xilinx Timing Simulation Library Component +// / / 16K-Bit Data and 2K-Bit Parity Dual Port Block RAM +// /___/ /\ Filename : RAMB16_S36_S36.v +// \ \ / \ Timestamp : Thu Mar 10 16:44:01 PST 2005 +// \___\/\___\ +// +// Revision: +// 03/23/04 - Initial version. +// 03/10/05 - Initialized outputs. +// End Revision + +`timescale 1 ps/1 ps + +module RAMB16_S36_S36 (DOA, DOB, DOPA, DOPB, ADDRA, ADDRB, CLKA, CLKB, DIA, DIB, DIPA, DIPB, ENA, ENB, SSRA, SSRB, WEA, WEB); + + parameter INIT_A = 36'h0; + parameter INIT_B = 36'h0; + parameter SRVAL_A = 36'h0; + parameter SRVAL_B = 36'h0; + parameter WRITE_MODE_A = "WRITE_FIRST"; + parameter WRITE_MODE_B = "WRITE_FIRST"; + parameter SIM_COLLISION_CHECK = "ALL"; + localparam SETUP_ALL = 1000; + localparam SETUP_READ_FIRST = 3000; + + parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + output [31:0] DOA; + output [3:0] DOPA; + output [31:0] DOB; + output [3:0] DOPB; + + input [8:0] ADDRA; + input [31:0] DIA; + input [3:0] DIPA; + input ENA, CLKA, WEA, SSRA; + input [8:0] ADDRB; + input [31:0] DIB; + input [3:0] DIPB; + input ENB, CLKB, WEB, SSRB; + + reg [31:0] doa_out = INIT_A[31:0]; + reg [3:0] dopa_out = INIT_A[35:32]; + reg [31:0] dob_out = INIT_B[31:0]; + reg [3:0] dopb_out = INIT_B[35:32]; + + reg [31:0] mem [511:0]; + reg [3:0] memp [511:0]; + + reg [8:0] count, countp; + reg [1:0] wr_mode_a, wr_mode_b; + + reg [5:0] dmi, dbi; + reg [5:0] pmi, pbi; + + wire [8:0] addra_int; + reg [8:0] addra_reg; + wire [31:0] dia_int; + wire [3:0] dipa_int; + wire ena_int, clka_int, wea_int, ssra_int; + reg ena_reg, wea_reg, ssra_reg; + wire [8:0] addrb_int; + reg [8:0] addrb_reg; + wire [31:0] dib_int; + wire [3:0] dipb_int; + wire enb_int, clkb_int, web_int, ssrb_int; + reg display_flag, output_flag; + reg enb_reg, web_reg, ssrb_reg; + + time time_clka, time_clkb; + time time_clka_clkb; + time time_clkb_clka; + + reg setup_all_a_b; + reg setup_all_b_a; + reg setup_zero; + reg setup_rf_a_b; + reg setup_rf_b_a; + reg [1:0] data_collision, data_collision_a_b, data_collision_b_a; + reg memory_collision, memory_collision_a_b, memory_collision_b_a; + reg change_clka; + reg change_clkb; + + wire [14:0] data_addra_int; + wire [14:0] data_addra_reg; + wire [14:0] data_addrb_int; + wire [14:0] data_addrb_reg; + + wire dia_enable = ena_int && wea_int; + wire dib_enable = enb_int && web_int; + + tri0 GSR = glbl.GSR; + wire gsr_int; + + buf b_gsr (gsr_int, GSR); + + buf b_doa [31:0] (DOA, doa_out); + buf b_dopa [3:0] (DOPA, dopa_out); + buf b_addra [8:0] (addra_int, ADDRA); + buf b_dia [31:0] (dia_int, DIA); + buf b_dipa [3:0] (dipa_int, DIPA); + buf b_ena (ena_int, ENA); + buf b_clka (clka_int, CLKA); + buf b_ssra (ssra_int, SSRA); + buf b_wea (wea_int, WEA); + + buf b_dob [31:0] (DOB, dob_out); + buf b_dopb [3:0] (DOPB, dopb_out); + buf b_addrb [8:0] (addrb_int, ADDRB); + buf b_dib [31:0] (dib_int, DIB); + buf b_dipb [3:0] (dipb_int, DIPB); + buf b_enb (enb_int, ENB); + buf b_clkb (clkb_int, CLKB); + buf b_ssrb (ssrb_int, SSRB); + buf b_web (web_int, WEB); + + + always @(gsr_int) + if (gsr_int) begin + assign {dopa_out, doa_out} = INIT_A; + assign {dopb_out, dob_out} = INIT_B; + end + else begin + deassign doa_out; + deassign dopa_out; + deassign dob_out; + deassign dopb_out; + end + + initial begin : initialize_mems + +`ifdef UNDEFINED + for (count = 0; count < 8; count = count + 1) begin + mem[count] = INIT_00[(count * 32) +: 32]; + mem[8 * 1 + count] = INIT_01[(count * 32) +: 32]; + mem[8 * 2 + count] = INIT_02[(count * 32) +: 32]; + mem[8 * 3 + count] = INIT_03[(count * 32) +: 32]; + mem[8 * 4 + count] = INIT_04[(count * 32) +: 32]; + mem[8 * 5 + count] = INIT_05[(count * 32) +: 32]; + mem[8 * 6 + count] = INIT_06[(count * 32) +: 32]; + mem[8 * 7 + count] = INIT_07[(count * 32) +: 32]; + mem[8 * 8 + count] = INIT_08[(count * 32) +: 32]; + mem[8 * 9 + count] = INIT_09[(count * 32) +: 32]; + mem[8 * 10 + count] = INIT_0A[(count * 32) +: 32]; + mem[8 * 11 + count] = INIT_0B[(count * 32) +: 32]; + mem[8 * 12 + count] = INIT_0C[(count * 32) +: 32]; + mem[8 * 13 + count] = INIT_0D[(count * 32) +: 32]; + mem[8 * 14 + count] = INIT_0E[(count * 32) +: 32]; + mem[8 * 15 + count] = INIT_0F[(count * 32) +: 32]; + mem[8 * 16 + count] = INIT_10[(count * 32) +: 32]; + mem[8 * 17 + count] = INIT_11[(count * 32) +: 32]; + mem[8 * 18 + count] = INIT_12[(count * 32) +: 32]; + mem[8 * 19 + count] = INIT_13[(count * 32) +: 32]; + mem[8 * 20 + count] = INIT_14[(count * 32) +: 32]; + mem[8 * 21 + count] = INIT_15[(count * 32) +: 32]; + mem[8 * 22 + count] = INIT_16[(count * 32) +: 32]; + mem[8 * 23 + count] = INIT_17[(count * 32) +: 32]; + mem[8 * 24 + count] = INIT_18[(count * 32) +: 32]; + mem[8 * 25 + count] = INIT_19[(count * 32) +: 32]; + mem[8 * 26 + count] = INIT_1A[(count * 32) +: 32]; + mem[8 * 27 + count] = INIT_1B[(count * 32) +: 32]; + mem[8 * 28 + count] = INIT_1C[(count * 32) +: 32]; + mem[8 * 29 + count] = INIT_1D[(count * 32) +: 32]; + mem[8 * 30 + count] = INIT_1E[(count * 32) +: 32]; + mem[8 * 31 + count] = INIT_1F[(count * 32) +: 32]; + mem[8 * 32 + count] = INIT_20[(count * 32) +: 32]; + mem[8 * 33 + count] = INIT_21[(count * 32) +: 32]; + mem[8 * 34 + count] = INIT_22[(count * 32) +: 32]; + mem[8 * 35 + count] = INIT_23[(count * 32) +: 32]; + mem[8 * 36 + count] = INIT_24[(count * 32) +: 32]; + mem[8 * 37 + count] = INIT_25[(count * 32) +: 32]; + mem[8 * 38 + count] = INIT_26[(count * 32) +: 32]; + mem[8 * 39 + count] = INIT_27[(count * 32) +: 32]; + mem[8 * 40 + count] = INIT_28[(count * 32) +: 32]; + mem[8 * 41 + count] = INIT_29[(count * 32) +: 32]; + mem[8 * 42 + count] = INIT_2A[(count * 32) +: 32]; + mem[8 * 43 + count] = INIT_2B[(count * 32) +: 32]; + mem[8 * 44 + count] = INIT_2C[(count * 32) +: 32]; + mem[8 * 45 + count] = INIT_2D[(count * 32) +: 32]; + mem[8 * 46 + count] = INIT_2E[(count * 32) +: 32]; + mem[8 * 47 + count] = INIT_2F[(count * 32) +: 32]; + mem[8 * 48 + count] = INIT_30[(count * 32) +: 32]; + mem[8 * 49 + count] = INIT_31[(count * 32) +: 32]; + mem[8 * 50 + count] = INIT_32[(count * 32) +: 32]; + mem[8 * 51 + count] = INIT_33[(count * 32) +: 32]; + mem[8 * 52 + count] = INIT_34[(count * 32) +: 32]; + mem[8 * 53 + count] = INIT_35[(count * 32) +: 32]; + mem[8 * 54 + count] = INIT_36[(count * 32) +: 32]; + mem[8 * 55 + count] = INIT_37[(count * 32) +: 32]; + mem[8 * 56 + count] = INIT_38[(count * 32) +: 32]; + mem[8 * 57 + count] = INIT_39[(count * 32) +: 32]; + mem[8 * 58 + count] = INIT_3A[(count * 32) +: 32]; + mem[8 * 59 + count] = INIT_3B[(count * 32) +: 32]; + mem[8 * 60 + count] = INIT_3C[(count * 32) +: 32]; + mem[8 * 61 + count] = INIT_3D[(count * 32) +: 32]; + mem[8 * 62 + count] = INIT_3E[(count * 32) +: 32]; + mem[8 * 63 + count] = INIT_3F[(count * 32) +: 32]; + end +`else + integer i; + for (i = 0; i < 512; i = i + 1) + begin + mem[i] = 0; + memp[i] = 0; + end + +`endif + +// initiate parity start +`ifdef UNDEFINED + for (countp = 0; countp < 64; countp = countp + 1) begin + memp[countp] = INITP_00[(countp * 4) +: 4]; + memp[64 * 1 + countp] = INITP_01[(countp * 4) +: 4]; + memp[64 * 2 + countp] = INITP_02[(countp * 4) +: 4]; + memp[64 * 3 + countp] = INITP_03[(countp * 4) +: 4]; + memp[64 * 4 + countp] = INITP_04[(countp * 4) +: 4]; + memp[64 * 5 + countp] = INITP_05[(countp * 4) +: 4]; + memp[64 * 6 + countp] = INITP_06[(countp * 4) +: 4]; + memp[64 * 7 + countp] = INITP_07[(countp * 4) +: 4]; + end +`endif +// initiate parity end + + change_clka <= 0; + change_clkb <= 0; + data_collision <= 0; + data_collision_a_b <= 0; + data_collision_b_a <= 0; + memory_collision <= 0; + memory_collision_a_b <= 0; + memory_collision_b_a <= 0; + setup_all_a_b <= 0; + setup_all_b_a <= 0; + setup_zero <= 0; + setup_rf_a_b <= 0; + setup_rf_b_a <= 0; + end + + assign data_addra_int = addra_int * 32; + assign data_addra_reg = addra_reg * 32; + assign data_addrb_int = addrb_int * 32; + assign data_addrb_reg = addrb_reg * 32; + + + initial begin + + display_flag = 1; + output_flag = 1; + + case (SIM_COLLISION_CHECK) + + "NONE" : begin + output_flag = 0; + display_flag = 0; + end + "WARNING_ONLY" : output_flag = 0; + "GENERATE_ONLY" : display_flag = 0; + "ALL" : ; + + default : begin + $display("Attribute Syntax Error : The Attribute SIM_COLLISION_CHECK on RAMB16_S36_S36 instance %m is set to %s. Legal values for this attribute are ALL, NONE, WARNING_ONLY or GENERATE_ONLY.", SIM_COLLISION_CHECK); + $finish; + end + + endcase // case(SIM_COLLISION_CHECK) + + end // initial begin + + + always @(posedge clka_int) begin + if ((output_flag || display_flag)) begin + time_clka = $time; + #0 time_clkb_clka = time_clka - time_clkb; + change_clka = ~change_clka; + end + end + + always @(posedge clkb_int) begin + if ((output_flag || display_flag)) begin + time_clkb = $time; + #0 time_clka_clkb = time_clkb - time_clka; + change_clkb = ~change_clkb; + end + end + + always @(change_clkb) begin + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_ALL)) + setup_all_a_b = 1; + if ((0 < time_clka_clkb) && (time_clka_clkb < SETUP_READ_FIRST)) + setup_rf_a_b = 1; + end + + always @(change_clka) begin + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_ALL)) + setup_all_b_a = 1; + if ((0 < time_clkb_clka) && (time_clkb_clka < SETUP_READ_FIRST)) + setup_rf_b_a = 1; + end + + always @(change_clkb or change_clka) begin + if ((time_clkb_clka == 0) && (time_clka_clkb == 0)) + setup_zero = 1; + end + + always @(posedge setup_zero) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_int[14:5] == data_addrb_int[14:5])) + memory_collision <= 1; + end + + always @(posedge setup_all_a_b or posedge setup_rf_a_b) begin + if ((ena_reg == 1) && (wea_reg == 1) && + (enb_int == 1) && (web_int == 1) && + (data_addra_reg[14:5] == data_addrb_int[14:5])) + memory_collision_a_b <= 1; + end + + always @(posedge setup_all_b_a or posedge setup_rf_b_a) begin + if ((ena_int == 1) && (wea_int == 1) && + (enb_reg == 1) && (web_reg == 1) && + (data_addra_int[14:5] == data_addrb_reg[14:5])) + memory_collision_b_a <= 1; + end + + always @(posedge setup_all_a_b) begin + if (data_addra_reg[14:5] == data_addrb_int[14:5]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) + 6'b000011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b010011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b010111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b011011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b100011 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_a_b <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision_a_b <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_a_b <= 0; + end + + + always @(posedge setup_all_b_a) begin + if (data_addra_int[14:5] == data_addrb_reg[14:5]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) + 6'b000011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b000111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b001011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b010111 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b011011 : begin data_collision_b_a <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b001001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b011001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b101001 : begin data_collision_b_a <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision_b_a <= 2'b01; display_wa_rb; end + endcase + end + end + setup_all_b_a <= 0; + end + + + always @(posedge setup_zero) begin + if (data_addra_int[14:5] == data_addrb_int[14:5]) begin + if ((ena_int == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_int}) + 6'b000011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b000111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b001011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b010011 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision <= 2'b10; display_wa_wb; end + 6'b100011 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b100111 : begin data_collision <= 2'b01; display_wa_wb; end + 6'b101011 : begin display_wa_wb; end + 6'b000001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b000101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b001001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b010001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b010101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b011001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b100001 : begin data_collision <= 2'b10; display_ra_wb; end +// 6'b100101 : begin data_collision <= 2'b00; display_ra_wb; end + 6'b101001 : begin data_collision <= 2'b10; display_ra_wb; end + 6'b000010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b000110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b001010 : begin data_collision <= 2'b01; display_wa_rb; end +// 6'b010010 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision <= 2'b00; display_wa_rb; end + 6'b100010 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b100110 : begin data_collision <= 2'b01; display_wa_rb; end + 6'b101010 : begin data_collision <= 2'b01; display_wa_rb; end + endcase + end + end + setup_zero <= 0; + end + + task display_ra_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S36_S36:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port A while a write was requested to the same address on Port B. The write will be successful however the read value on Port A is unknown until the next CLKA cycle.", $time/1000.0, addra_int); + end + endtask + + task display_wa_rb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S36_S36:%m at simulation time %.3f ns\nA read was performed on address %h (hex) of Port B while a write was requested to the same address on Port A. The write will be successful however the read value on Port B is unknown until the next CLKB cycle.", $time/1000.0, addrb_int); + end + endtask + + task display_wa_wb; + begin + if (display_flag) + $display("Memory Collision Error on RAMB16_S36_S36:%m at simulation time %.3f ns\nA write was requested to the same address simultaneously at both Port A and Port B of the RAM. The contents written to the RAM at address location %h (hex) of Port A and address location %h (hex) of Port B are unknown.", $time/1000.0, addra_int, addrb_int); + end + endtask + + + always @(posedge setup_rf_a_b) begin + if (data_addra_reg[14:5] == data_addrb_int[14:5]) begin + if ((ena_reg == 1) && (enb_int == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_reg, web_int}) +// 6'b000011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b001011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end + 6'b010011 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b010111 : begin data_collision_a_b <= 2'b11; display_wa_wb; end + 6'b011011 : begin data_collision_a_b <= 2'b10; display_wa_wb; end +// 6'b100011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b100111 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b101011 : begin data_collision_a_b <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b001001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b010101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b011001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b100101 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b101001 : begin data_collision_a_b <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + 6'b010010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b010110 : begin data_collision_a_b <= 2'b01; display_wa_rb; end + 6'b011010 : begin data_collision_a_b <= 2'b01; display_wa_rb; end +// 6'b100010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_a_b <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_a_b <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_a_b <= 0; + end + + + always @(posedge setup_rf_b_a) begin + if (data_addra_int[14:5] == data_addrb_reg[14:5]) begin + if ((ena_int == 1) && (enb_reg == 1)) begin + case ({wr_mode_a, wr_mode_b, wea_int, web_reg}) +// 6'b000011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b000111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b001011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b010011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b010111 : begin data_collision_b_a <= 2'b11; display_wa_wb; end +// 6'b011011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b100011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end + 6'b100111 : begin data_collision_b_a <= 2'b01; display_wa_wb; end +// 6'b101011 : begin data_collision_b_a <= 2'b00; display_wa_wb; end +// 6'b000001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b000101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b001001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b010001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b010101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b011001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b100001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end + 6'b100101 : begin data_collision_b_a <= 2'b10; display_ra_wb; end +// 6'b101001 : begin data_collision_b_a <= 2'b00; display_ra_wb; end +// 6'b000010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b000110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b001010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b010110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b011010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b100110 : begin data_collision_b_a <= 2'b00; display_wa_rb; end +// 6'b101010 : begin data_collision_b_a <= 2'b00; display_wa_rb; end + endcase + end + end + setup_rf_b_a <= 0; + end + + + always @(posedge clka_int) begin + if ((output_flag || display_flag)) begin + addra_reg <= addra_int; + ena_reg <= ena_int; + ssra_reg <= ssra_int; + wea_reg <= wea_int; + end + end + + always @(posedge clkb_int) begin + if ((output_flag || display_flag)) begin + addrb_reg <= addrb_int; + enb_reg <= enb_int; + ssrb_reg <= ssrb_int; + web_reg <= web_int; + end + end + + + // Data + always @(posedge memory_collision) begin + if ((output_flag || display_flag)) begin + mem[addra_int] <= 32'bx; + memory_collision <= 0; + end + + end + + always @(posedge memory_collision_a_b) begin + if ((output_flag || display_flag)) begin + mem[addra_reg] <= 32'bx; + memory_collision_a_b <= 0; + end + end + + always @(posedge memory_collision_b_a) begin + if ((output_flag || display_flag)) begin + mem[addra_int] <= 32'bx; + memory_collision_b_a <= 0; + end + end + + always @(posedge data_collision[1]) begin + if (ssra_int == 0 && output_flag) begin + doa_out <= #100 32'bX; + end + data_collision[1] <= 0; + end + + always @(posedge data_collision[0]) begin + if (ssrb_int == 0 && output_flag) begin + dob_out <= #100 32'bX; + end + data_collision[0] <= 0; + end + + always @(posedge data_collision_a_b[1]) begin + if (ssra_reg == 0 && output_flag) begin + doa_out <= #100 32'bX; + end + data_collision_a_b[1] <= 0; + end + + always @(posedge data_collision_a_b[0]) begin + if (ssrb_int == 0 && output_flag) begin + dob_out <= #100 32'bX; + end + data_collision_a_b[0] <= 0; + end + + always @(posedge data_collision_b_a[1]) begin + if (ssra_int == 0 && output_flag) begin + doa_out <= #100 32'bX; + end + data_collision_b_a[1] <= 0; + end + + always @(posedge data_collision_b_a[0]) begin + if (ssrb_reg == 0 && output_flag) begin + dob_out <= #100 32'bX; + end + data_collision_b_a[0] <= 0; + end + +// x parity start + always @(posedge memory_collision) begin + if ((output_flag || display_flag)) + memp[addra_int] <= 4'bx; + end + + always @(posedge memory_collision_a_b) begin + if ((output_flag || display_flag)) + memp[addra_reg] <= 4'bx; + end + + always @(posedge memory_collision_b_a) begin + if ((output_flag || display_flag)) + memp[addra_int] <= 4'bx; + end + + always @(posedge data_collision[1]) begin + if (ssra_int == 0 && output_flag) begin + dopa_out <= #100 4'bX; + end + end + + always @(posedge data_collision_a_b[1]) begin + if (ssra_reg == 0 && output_flag) begin + dopa_out <= #100 4'bX; + end + end + + + always @(posedge data_collision_b_a[1]) begin + if (ssra_int == 0 && output_flag) begin + dopa_out <= #100 4'bX; + end + end + + always @(posedge data_collision[0]) begin + if (ssrb_int == 0 && output_flag) begin + dopb_out <= #100 4'bx; + end + end + + always @(posedge data_collision_a_b[0]) begin + if (ssrb_int == 0 && output_flag) begin + dopb_out <= #100 4'bx; + end + end + + always @(posedge data_collision_b_a[0]) begin + if (ssrb_reg == 0 && output_flag) begin + dopb_out <= #100 4'bx; + end + end +// x parity end + + initial begin + case (WRITE_MODE_A) + "WRITE_FIRST" : wr_mode_a <= 2'b00; + "READ_FIRST" : wr_mode_a <= 2'b01; + "NO_CHANGE" : wr_mode_a <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_A on RAMB16_S36_S36 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_A); + $finish; + end + endcase + end + + initial begin + case (WRITE_MODE_B) + "WRITE_FIRST" : wr_mode_b <= 2'b00; + "READ_FIRST" : wr_mode_b <= 2'b01; + "NO_CHANGE" : wr_mode_b <= 2'b10; + default : begin + $display("Attribute Syntax Error : The Attribute WRITE_MODE_B on RAMB16_S36_S36 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE_B); + $finish; + end + endcase + end + + + // Port A + always @(posedge clka_int) begin + + if (ena_int == 1'b1) begin + + if (ssra_int == 1'b1) begin + {dopa_out, doa_out} <= #100 SRVAL_A; + end + else begin + if (wea_int == 1'b1) begin + if (wr_mode_a == 2'b00) begin + doa_out <= #100 dia_int; + dopa_out <= #100 dipa_int; + end + else if (wr_mode_a == 2'b01) begin + + doa_out <= #100 mem[addra_int]; + dopa_out <= #100 memp[addra_int]; + + end + end + else begin + + doa_out <= #100 mem[addra_int]; + dopa_out <= #100 memp[addra_int]; + + end + end + + // memory + if (wea_int == 1'b1) begin + mem[addra_int] <= dia_int; + memp[addra_int] <= dipa_int; + end + + end + end + + + // Port B + always @(posedge clkb_int) begin + + if (enb_int == 1'b1) begin + + if (ssrb_int == 1'b1) begin + {dopb_out, dob_out} <= #100 SRVAL_B; + end + else begin + if (web_int == 1'b1) begin + if (wr_mode_b == 2'b00) begin + dob_out <= #100 dib_int; + dopb_out <= #100 dipb_int; + end + else if (wr_mode_b == 2'b01) begin + dob_out <= #100 mem[addrb_int]; + dopb_out <= #100 memp[addrb_int]; + end + end + else begin + dob_out <= #100 mem[addrb_int]; + dopb_out <= #100 memp[addrb_int]; + end + end + + // memory + if (web_int == 1'b1) begin + mem[addrb_int] <= dib_int; + memp[addrb_int] <= dipb_int; + end + + end + end + + +endmodule + +`endif diff --git a/usrp2/fpga/eth/rtl/verilog/elastic_buffer.v b/usrp2/fpga/eth/rtl/verilog/elastic_buffer.v new file mode 100644 index 000000000..56c821b7e --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/elastic_buffer.v @@ -0,0 +1,93 @@ + + +module elastic_buffer + ( input rx_clk, + input tx_clk, + input rst, + + input [7:0] rxd, + input rx_dv, + input rx_er, + input crs, + input col, + + output [7:0] rxd_ret, + output rx_dv_ret, + output rx_er_ret, + output crs_ret, + output col_ret ); + + reg [3:0] addr_wr,addr_wr_gray,awg_d1,awg_d2,addr_wr_gray_ret,awgr_d1,addr_wr_ungray,addr_rd; + + reg [11:0] buffer [0:15]; + integer i; + initial + for(i=0;i<16;i=i+1) + buffer[i] <= 0; + + reg [7:0] rxd_d1, rxd_d2; + reg rx_dv_d1,rx_er_d1,crs_d1,col_d1, rx_dv_d2,rx_er_d2,crs_d2,col_d2; + wire rx_dv_ret_adv; + reg rx_dv_ontime; + + always @(posedge rx_clk) + {col_d1,crs_d1,rx_er_d1,rx_dv_d1,rxd_d1} <= {col,crs,rx_er,rx_dv,rxd}; + + always @(posedge rx_clk) + {col_d2,crs_d2,rx_er_d2,rx_dv_d2,rxd_d2} <= {col_d1,crs_d1,rx_er_d1,rx_dv_d1,rxd_d1}; + + always @(posedge rx_clk) + buffer[addr_wr] <= {col_d2,crs_d2,rx_er_d2,rx_dv_d1,rxd_d2}; + + always @(posedge rx_clk or posedge rst) + if(rst) addr_wr <= 0; + else addr_wr <= addr_wr + 1; + + always @(posedge rx_clk) + begin + addr_wr_gray <= {addr_wr[3],^addr_wr[3:2],^addr_wr[2:1],^addr_wr[1:0]}; + awg_d1 <= addr_wr_gray; + awg_d2 <= awg_d1; + end + + always @(posedge tx_clk) + begin + addr_wr_gray_ret <= awg_d2; + awgr_d1 <= addr_wr_gray_ret; + addr_wr_ungray <= {awgr_d1[3],^awgr_d1[3:2],^awgr_d1[3:1],^awgr_d1[3:0]}; + end + + wire [3:0] addr_delta = addr_rd-addr_wr_ungray; + reg [1:0] direction; + localparam retard = 2'd0; + localparam good = 2'd1; + localparam advance = 2'd2; + localparam wayoff = 2'd3; + + always @* + case(addr_delta) + 4'd1, 4'd2, 4'd3, 4'd4, 4'd5 : direction <= retard; + 4'd15, 4'd14, 4'd13, 4'd12, 4'd11 : direction <= advance; + 4'd0 : direction <= good; + default : direction <= wayoff; + endcase // case(addr_delta) + + always @(posedge tx_clk or posedge rst) + if(rst) + addr_rd <= 0; + else if(rx_dv_ret_adv | rx_dv_ontime) + addr_rd <= addr_rd + 1; + else + case(direction) + retard : addr_rd <= addr_rd; + advance : addr_rd <= addr_rd + 2; + good : addr_rd <= addr_rd + 1; + wayoff : addr_rd <= addr_wr_ungray; + endcase // case(direction) + + assign {col_ret,crs_ret,rx_er_ret,rx_dv_ret_adv,rxd_ret} = buffer[addr_rd]; + always @(posedge tx_clk) + rx_dv_ontime <= rx_dv_ret_adv; + + assign rx_dv_ret = rx_dv_ontime; +endmodule // elastic_buffer diff --git a/usrp2/fpga/eth/rtl/verilog/elastic_buffer_tb.v b/usrp2/fpga/eth/rtl/verilog/elastic_buffer_tb.v new file mode 100644 index 000000000..757049ec4 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/elastic_buffer_tb.v @@ -0,0 +1,66 @@ + +module elastic_buffer_tb; + + reg rx_clk = 0, tx_clk = 0, rst = 1; + + reg [7:0] rxd; + wire [7:0] rxd_ret; + reg rx_dv, rx_er, crs, col; + wire rx_dv_ret, rx_er_ret, crs_ret, col_ret; + + elastic_buffer elastic_buffer + (.rx_clk(rx_clk),.tx_clk(tx_clk),.rst(rst), + .rxd(rxd),.rx_dv(rx_dv),.rx_er(rx_er),.crs(crs),.col(col), + .rxd_ret(rxd_ret),.rx_dv_ret(rx_dv_ret),.rx_er_ret(rx_er_ret), + .crs_ret(crs_ret),.col_ret(col_ret) ); + + always #100 rx_clk = ~rx_clk; + always #101 tx_clk = ~tx_clk; + initial #950 rst = 0; + + initial + begin + {col,crs,rx_er,rx_dv,rxd} <= 0; + @(negedge rst); + @(posedge rx_clk); + + repeat (13) + begin + repeat (284) + @(posedge rx_clk); + SendPKT; + end + repeat (100) + @(posedge rx_clk); + $finish; + end // initial begin + + reg [7:0] rxd_ret_d1; + always @(posedge tx_clk) + rxd_ret_d1 <= rxd_ret; + + wire [7:0] diff = rxd_ret_d1 - rxd_ret; + + wire error = rx_dv_ret && (diff != 8'hFF); + + task SendPKT; + begin + {col,crs,rx_er,rx_dv,rxd} <= 0; + @(posedge rx_clk); + {col,crs,rx_er,rx_dv,rxd} <= {4'hF,8'd1}; + @(posedge rx_clk); + repeat (250) + begin + rxd <= rxd + 1; + @(posedge rx_clk); + end + {col,crs,rx_er,rx_dv,rxd} <= 0; + @(posedge rx_clk); + end + endtask // SendPKT + + initial begin + $dumpfile("elastic_buffer_tb.vcd"); + $dumpvars(0,elastic_buffer_tb); + end +endmodule // elastic_buffer_tb diff --git a/usrp2/fpga/eth/rtl/verilog/eth_miim.v b/usrp2/fpga/eth/rtl/verilog/eth_miim.v new file mode 100644 index 000000000..a15c94205 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/eth_miim.v @@ -0,0 +1,470 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// eth_miim.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects/ethmac/ ////
+//// ////
+//// Author(s): ////
+//// - Igor Mohor (igorM@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: eth_miim.v,v $
+// Revision 1.3 2006/01/19 14:07:53 maverickist
+// verification is complete.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:44 Administrator
+// no message
+//
+// Revision 1.4 2005/08/16 12:07:57 Administrator
+// no message
+//
+// Revision 1.3 2005/05/19 07:04:29 Administrator
+// no message
+//
+// Revision 1.2 2005/04/27 15:58:46 Administrator
+// no message
+//
+// Revision 1.1.1.1 2004/12/15 06:38:54 Administrator
+// no message
+//
+// Revision 1.5 2003/05/16 10:08:27 mohor
+// Busy was set 2 cycles too late. Reported by Dennis Scott.
+//
+// Revision 1.4 2002/08/14 18:32:10 mohor
+// - Busy signal was not set on time when scan status operation was performed
+// and clock was divided with more than 2.
+// - Nvalid remains valid two more clocks (was previously cleared too soon).
+//
+// Revision 1.3 2002/01/23 10:28:16 mohor
+// Link in the header changed.
+//
+// Revision 1.2 2001/10/19 08:43:51 mohor
+// eth_timescale.v changed to timescale.v This is done because of the
+// simulation of the few cores in a one joined project.
+//
+// Revision 1.1 2001/08/06 14:44:29 mohor
+// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex).
+// Include files fixed to contain no path.
+// File names and module names changed ta have a eth_ prologue in the name.
+// File eth_timescale.v is used to define timescale
+// All pin names on the top module are changed to contain _I, _O or _OE at the end.
+// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O
+// and Mdo_OE. The bidirectional signal must be created on the top level. This
+// is done due to the ASIC tools.
+//
+// Revision 1.2 2001/08/02 09:25:31 mohor
+// Unconnected signals are now connected.
+//
+// Revision 1.1 2001/07/30 21:23:42 mohor
+// Directory structure changed. Files checked and joind together.
+//
+// Revision 1.3 2001/06/01 22:28:56 mohor
+// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated.
+//
+//
+
+module eth_miim
+(
+ Clk,
+ Reset,
+ Divider,
+ NoPre,
+ CtrlData,
+ Rgad,
+ Fiad,
+ WCtrlData,
+ RStat,
+ ScanStat,
+ Mdio,
+ Mdc,
+ Busy,
+ Prsd,
+ LinkFail,
+ Nvalid,
+ WCtrlDataStart,
+ RStatStart,
+ UpdateMIIRX_DATAReg
+);
+
+input Clk; // Host Clock
+input Reset; // General Reset
+input [7:0] Divider; // Divider for the host clock
+input [15:0] CtrlData; // Control Data (to be written to the PHY reg.)
+input [4:0] Rgad; // Register Address (within the PHY)
+input [4:0] Fiad; // PHY Address
+input NoPre; // No Preamble (no 32-bit preamble)
+input WCtrlData; // Write Control Data operation
+input RStat; // Read Status operation
+input ScanStat; // Scan Status operation
+inout Mdio; // MII Management Data In
+
+output Mdc; // MII Management Data Clock
+
+output Busy; // Busy Signal
+output LinkFail; // Link Integrity Signal
+output Nvalid; // Invalid Status (qualifier for the valid scan result)
+
+output [15:0] Prsd; // Read Status Data (data read from the PHY)
+
+output WCtrlDataStart; // This signals resets the WCTRLDATA bit in the MIIM Command register
+output RStatStart; // This signal resets the RSTAT BIT in the MIIM Command register
+output UpdateMIIRX_DATAReg;// Updates MII RX_DATA register with read data
+
+//parameter Tp = 1;
+
+
+reg Nvalid;
+reg EndBusy_d; // Pre-end Busy signal
+reg EndBusy; // End Busy signal (stops the operation in progress)
+
+reg WCtrlData_q1; // Write Control Data operation delayed 1 Clk cycle
+reg WCtrlData_q2; // Write Control Data operation delayed 2 Clk cycles
+reg WCtrlData_q3; // Write Control Data operation delayed 3 Clk cycles
+reg WCtrlDataStart; // Start Write Control Data Command (positive edge detected)
+reg WCtrlDataStart_q;
+reg WCtrlDataStart_q1; // Start Write Control Data Command delayed 1 Mdc cycle
+reg WCtrlDataStart_q2; // Start Write Control Data Command delayed 2 Mdc cycles
+
+reg RStat_q1; // Read Status operation delayed 1 Clk cycle
+reg RStat_q2; // Read Status operation delayed 2 Clk cycles
+reg RStat_q3; // Read Status operation delayed 3 Clk cycles
+reg RStatStart; // Start Read Status Command (positive edge detected)
+reg RStatStart_q1; // Start Read Status Command delayed 1 Mdc cycle
+reg RStatStart_q2; // Start Read Status Command delayed 2 Mdc cycles
+
+reg ScanStat_q1; // Scan Status operation delayed 1 cycle
+reg ScanStat_q2; // Scan Status operation delayed 2 cycles
+reg SyncStatMdcEn; // Scan Status operation delayed at least cycles and synchronized to MdcEn
+
+wire WriteDataOp; // Write Data Operation (positive edge detected)
+wire ReadStatusOp; // Read Status Operation (positive edge detected)
+wire ScanStatusOp; // Scan Status Operation (positive edge detected)
+wire StartOp; // Start Operation (start of any of the preceding operations)
+wire EndOp; // End of Operation
+
+reg InProgress; // Operation in progress
+reg InProgress_q1; // Operation in progress delayed 1 Mdc cycle
+reg InProgress_q2; // Operation in progress delayed 2 Mdc cycles
+reg InProgress_q3; // Operation in progress delayed 3 Mdc cycles
+
+reg WriteOp; // Write Operation Latch (When asserted, write operation is in progress)
+reg [6:0] BitCounter; // Bit Counter
+
+
+wire [3:0] ByteSelect; // Byte Select defines which byte (preamble, data, operation, etc.) is loaded and shifted through the shift register.
+wire MdcEn; // MII Management Data Clock Enable signal is asserted for one Clk period before Mdc rises.
+wire ShiftedBit; // This bit is output of the shift register and is connected to the Mdo signal
+
+
+wire LatchByte1_d2;
+wire LatchByte0_d2;
+reg LatchByte1_d;
+reg LatchByte0_d;
+reg [1:0] LatchByte; // Latch Byte selects which part of Read Status Data is updated from the shift register
+
+reg UpdateMIIRX_DATAReg;// Updates MII RX_DATA register with read data
+
+wire Mdo; // MII Management Data Output
+wire MdoEn; // MII Management Data Output Enable
+wire Mdi;
+
+assign Mdi=Mdio;
+assign Mdio=MdoEn?Mdo:1'bz;
+
+
+
+// Generation of the EndBusy signal. It is used for ending the MII Management operation.
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ EndBusy_d <= 1'b0;
+ EndBusy <= 1'b0;
+ end
+ else
+ begin
+ EndBusy_d <= ~InProgress_q2 & InProgress_q3;
+ EndBusy <= EndBusy_d;
+ end
+end
+
+
+// Update MII RX_DATA register
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ UpdateMIIRX_DATAReg <= 0;
+ else
+ if(EndBusy & ~WCtrlDataStart_q)
+ UpdateMIIRX_DATAReg <= 1;
+ else
+ UpdateMIIRX_DATAReg <= 0;
+end
+
+
+
+// Generation of the delayed signals used for positive edge triggering.
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ WCtrlData_q1 <= 1'b0;
+ WCtrlData_q2 <= 1'b0;
+ WCtrlData_q3 <= 1'b0;
+
+ RStat_q1 <= 1'b0;
+ RStat_q2 <= 1'b0;
+ RStat_q3 <= 1'b0;
+
+ ScanStat_q1 <= 1'b0;
+ ScanStat_q2 <= 1'b0;
+ SyncStatMdcEn <= 1'b0;
+ end
+ else
+ begin
+ WCtrlData_q1 <= WCtrlData;
+ WCtrlData_q2 <= WCtrlData_q1;
+ WCtrlData_q3 <= WCtrlData_q2;
+
+ RStat_q1 <= RStat;
+ RStat_q2 <= RStat_q1;
+ RStat_q3 <= RStat_q2;
+
+ ScanStat_q1 <= ScanStat;
+ ScanStat_q2 <= ScanStat_q1;
+ if(MdcEn)
+ SyncStatMdcEn <= ScanStat_q2;
+ end
+end
+
+
+// Generation of the Start Commands (Write Control Data or Read Status)
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ WCtrlDataStart <= 1'b0;
+ WCtrlDataStart_q <= 1'b0;
+ RStatStart <= 1'b0;
+ end
+ else
+ begin
+ if(EndBusy)
+ begin
+ WCtrlDataStart <= 1'b0;
+ RStatStart <= 1'b0;
+ end
+ else
+ begin
+ if(WCtrlData_q2 & ~WCtrlData_q3)
+ WCtrlDataStart <= 1'b1;
+ if(RStat_q2 & ~RStat_q3)
+ RStatStart <= 1'b1;
+ WCtrlDataStart_q <= WCtrlDataStart;
+ end
+ end
+end
+
+
+// Generation of the Nvalid signal (indicates when the status is invalid)
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ Nvalid <= 1'b0;
+ else
+ begin
+ if(~InProgress_q2 & InProgress_q3)
+ begin
+ Nvalid <= 1'b0;
+ end
+ else
+ begin
+ if(ScanStat_q2 & ~SyncStatMdcEn)
+ Nvalid <= 1'b1;
+ end
+ end
+end
+
+// Signals used for the generation of the Operation signals (positive edge)
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ WCtrlDataStart_q1 <= 1'b0;
+ WCtrlDataStart_q2 <= 1'b0;
+
+ RStatStart_q1 <= 1'b0;
+ RStatStart_q2 <= 1'b0;
+
+ InProgress_q1 <= 1'b0;
+ InProgress_q2 <= 1'b0;
+ InProgress_q3 <= 1'b0;
+
+ LatchByte0_d <= 1'b0;
+ LatchByte1_d <= 1'b0;
+
+ LatchByte <= 2'b00;
+ end
+ else
+ begin
+ if(MdcEn)
+ begin
+ WCtrlDataStart_q1 <= WCtrlDataStart;
+ WCtrlDataStart_q2 <= WCtrlDataStart_q1;
+
+ RStatStart_q1 <= RStatStart;
+ RStatStart_q2 <= RStatStart_q1;
+
+ LatchByte[0] <= LatchByte0_d;
+ LatchByte[1] <= LatchByte1_d;
+
+ LatchByte0_d <= LatchByte0_d2;
+ LatchByte1_d <= LatchByte1_d2;
+
+ InProgress_q1 <= InProgress;
+ InProgress_q2 <= InProgress_q1;
+ InProgress_q3 <= InProgress_q2;
+ end
+ end
+end
+
+
+// Generation of the Operation signals
+assign WriteDataOp = WCtrlDataStart_q1 & ~WCtrlDataStart_q2;
+assign ReadStatusOp = RStatStart_q1 & ~RStatStart_q2;
+assign ScanStatusOp = SyncStatMdcEn & ~InProgress & ~InProgress_q1 & ~InProgress_q2;
+assign StartOp = WriteDataOp | ReadStatusOp | ScanStatusOp;
+
+// Busy
+reg Busy;
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Busy <=0;
+ else if(WCtrlData | WCtrlDataStart | RStat | RStatStart | SyncStatMdcEn | EndBusy | InProgress | InProgress_q3 | Nvalid)
+ Busy <=1;
+ else
+ Busy <=0;
+
+//assign Busy = WCtrlData | WCtrlDataStart | RStat | RStatStart | SyncStatMdcEn | EndBusy | InProgress | InProgress_q3 | Nvalid;
+
+
+// Generation of the InProgress signal (indicates when an operation is in progress)
+// Generation of the WriteOp signal (indicates when a write is in progress)
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ InProgress <= 1'b0;
+ WriteOp <= 1'b0;
+ end
+ else
+ begin
+ if(MdcEn)
+ begin
+ if(StartOp)
+ begin
+ if(~InProgress)
+ WriteOp <= WriteDataOp;
+ InProgress <= 1'b1;
+ end
+ else
+ begin
+ if(EndOp)
+ begin
+ InProgress <= 1'b0;
+ WriteOp <= 1'b0;
+ end
+ end
+ end
+ end
+end
+
+
+
+// Bit Counter counts from 0 to 63 (from 32 to 63 when NoPre is asserted)
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ BitCounter[6:0] <= 7'h0;
+ else
+ begin
+ if(MdcEn)
+ begin
+ if(InProgress)
+ begin
+ if(NoPre & ( BitCounter == 7'h0 ))
+ BitCounter[6:0] <= 7'h21;
+ else
+ BitCounter[6:0] <= BitCounter[6:0] + 1'b1;
+ end
+ else
+ BitCounter[6:0] <= 7'h0;
+ end
+ end
+end
+
+
+// Operation ends when the Bit Counter reaches 63
+assign EndOp = BitCounter==63;
+
+assign ByteSelect[0] = InProgress & ((NoPre & (BitCounter == 7'h0)) | (~NoPre & (BitCounter == 7'h20)));
+assign ByteSelect[1] = InProgress & (BitCounter == 7'h28);
+assign ByteSelect[2] = InProgress & WriteOp & (BitCounter == 7'h30);
+assign ByteSelect[3] = InProgress & WriteOp & (BitCounter == 7'h38);
+
+
+// Latch Byte selects which part of Read Status Data is updated from the shift register
+assign LatchByte1_d2 = InProgress & ~WriteOp & BitCounter == 7'h37;
+assign LatchByte0_d2 = InProgress & ~WriteOp & BitCounter == 7'h3F;
+
+wire MdcEn_n;
+
+// Connecting the Clock Generator Module
+eth_clockgen clkgen(.Clk(Clk), .Reset(Reset), .Divider(Divider[7:0]), .MdcEn(MdcEn), .MdcEn_n(MdcEn_n), .Mdc(Mdc)
+ );
+
+// Connecting the Shift Register Module
+eth_shiftreg shftrg(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .Mdi(Mdi), .Fiad(Fiad), .Rgad(Rgad),
+ .CtrlData(CtrlData), .WriteOp(WriteOp), .ByteSelect(ByteSelect), .LatchByte(LatchByte),
+ .ShiftedBit(ShiftedBit), .Prsd(Prsd), .LinkFail(LinkFail)
+ );
+
+// Connecting the Output Control Module
+eth_outputcontrol outctrl(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .InProgress(InProgress),
+ .ShiftedBit(ShiftedBit), .BitCounter(BitCounter), .WriteOp(WriteOp), .NoPre(NoPre),
+ .Mdo(Mdo), .MdoEn(MdoEn)
+ );
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/flow_ctrl_rx.v b/usrp2/fpga/eth/rtl/verilog/flow_ctrl_rx.v new file mode 100644 index 000000000..7ded9e08b --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/flow_ctrl_rx.v @@ -0,0 +1,85 @@ +
+// RX side of flow control -- when we are running out of RX space, send a PAUSE
+
+module flow_ctrl_rx
+ (input rst,
+ //host processor
+ input pause_frame_send_en,
+ input [15:0] pause_quanta_set,
+ input [15:0] fc_hwmark,
+ input [15:0] fc_lwmark,
+ // From MAC_rx_ctrl
+ input rx_clk,
+ input [15:0] rx_fifo_space,
+ // MAC_tx_ctrl
+ input tx_clk,
+ output reg xoff_gen,
+ output reg xon_gen,
+ input xoff_gen_complete,
+ input xon_gen_complete
+ );
+
+ // ******************************************************************************
+ // Force our TX to send a PAUSE frame because our RX is nearly full
+ // ******************************************************************************
+
+ reg xon_int, xoff_int;
+ reg [21:0] countdown;
+
+ always @(posedge rx_clk or posedge rst)
+ if(rst)
+ begin
+ xon_int <= 0;
+ xoff_int <= 0;
+ end
+ else
+ begin
+ xon_int <= 0;
+ xoff_int <= 0;
+ if(pause_frame_send_en)
+ if(countdown == 0)
+ if(rx_fifo_space < fc_lwmark)
+ xoff_int <= 1;
+ else
+ ;
+ else
+ if(rx_fifo_space > fc_hwmark)
+ xon_int <= 1;
+ end // else: !if(rst)
+
+ reg xoff_int_d1, xon_int_d1;
+
+ always @(posedge rx_clk)
+ xon_int_d1 <= xon_int;
+ always @(posedge rx_clk)
+ xoff_int_d1 <= xoff_int;
+
+ always @ (posedge tx_clk or posedge rst)
+ if (rst)
+ xoff_gen <=0;
+ else if (xoff_gen_complete)
+ xoff_gen <=0;
+ else if (xoff_int | xoff_int_d1)
+ xoff_gen <=1;
+
+ always @ (posedge tx_clk or posedge rst)
+ if (rst)
+ xon_gen <=0;
+ else if (xon_gen_complete)
+ xon_gen <=0;
+ else if (xon_int | xon_int_d1)
+ xon_gen <=1;
+
+ wire [15:0] pq_reduced = pause_quanta_set - 2;
+
+ always @(posedge tx_clk or posedge rst)
+ if(rst)
+ countdown <= 0;
+ else if(xoff_gen)
+ countdown <= {pq_reduced,6'd0};
+ else if(xon_gen)
+ countdown <= 0;
+ else if(countdown != 0)
+ countdown <= countdown - 1;
+
+endmodule // flow_ctrl
diff --git a/usrp2/fpga/eth/rtl/verilog/flow_ctrl_tx.v b/usrp2/fpga/eth/rtl/verilog/flow_ctrl_tx.v new file mode 100644 index 000000000..9f7556de4 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/flow_ctrl_tx.v @@ -0,0 +1,36 @@ +
+// TX side of flow control -- when other side sends PAUSE, we wait
+
+module flow_ctrl_tx
+ (input rst,
+ input tx_clk,
+ //host processor
+ input tx_pause_en,
+ // From MAC_rx_ctrl
+ input [15:0] pause_quanta,
+ input pause_quanta_val,
+ // MAC_tx_ctrl
+ output pause_apply,
+ input pause_quanta_sub);
+
+ // ******************************************************************************
+ // Inhibit our TX from transmitting because they sent us a PAUSE frame
+ // ******************************************************************************
+
+ reg [15:0] pause_quanta_counter;
+ reg pqval_d1, pqval_d2;
+
+ always @(posedge tx_clk) pqval_d1 <= pause_quanta_val;
+ always @(posedge tx_clk) pqval_d2 <= pqval_d1;
+
+ always @ (posedge tx_clk or posedge rst)
+ if (rst)
+ pause_quanta_counter <= 0;
+ else if (pqval_d1 & ~pqval_d2)
+ pause_quanta_counter <= pause_quanta;
+ else if((pause_quanta_counter!=0) & pause_quanta_sub)
+ pause_quanta_counter <= pause_quanta_counter - 1;
+
+ assign pause_apply = tx_pause_en & (pause_quanta_counter != 0);
+
+endmodule // flow_ctrl
diff --git a/usrp2/fpga/eth/rtl/verilog/header.vh b/usrp2/fpga/eth/rtl/verilog/header.vh new file mode 100644 index 000000000..ca0b580e4 --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/header.vh @@ -0,0 +1,7 @@ +`define MAC_SOURCE_REPLACE_EN 1
+`define MAC_TARGET_CHECK_EN 1
+`define MAC_BROADCAST_FILTER_EN 1
+`define MAC_TX_FF_DEPTH 9
+`define MAC_RX_FF_DEPTH 9
+`define MAC_TARGET_XILINX 1
+// `define MAC_TARGET_ALTERA 1
diff --git a/usrp2/fpga/eth/rtl/verilog/miim/eth_clockgen.v b/usrp2/fpga/eth/rtl/verilog/miim/eth_clockgen.v new file mode 100644 index 000000000..9da732f7f --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/miim/eth_clockgen.v @@ -0,0 +1,141 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// eth_clockgen.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects/ethmac/ ////
+//// ////
+//// Author(s): ////
+//// - Igor Mohor (igorM@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: eth_clockgen.v,v $
+// Revision 1.2 2005/12/13 12:54:49 maverickist
+// first simulation passed
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+// Revision 1.2 2005/04/27 15:58:45 Administrator
+// no message
+//
+// Revision 1.1.1.1 2004/12/15 06:38:54 Administrator
+// no message
+//
+// Revision 1.3 2002/01/23 10:28:16 mohor
+// Link in the header changed.
+//
+// Revision 1.2 2001/10/19 08:43:51 mohor
+// eth_timescale.v changed to timescale.v This is done because of the
+// simulation of the few cores in a one joined project.
+//
+// Revision 1.1 2001/08/06 14:44:29 mohor
+// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex).
+// Include files fixed to contain no path.
+// File names and module names changed ta have a eth_ prologue in the name.
+// File eth_timescale.v is used to define timescale
+// All pin names on the top module are changed to contain _I, _O or _OE at the end.
+// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O
+// and Mdo_OE. The bidirectional signal must be created on the top level. This
+// is done due to the ASIC tools.
+//
+// Revision 1.1 2001/07/30 21:23:42 mohor
+// Directory structure changed. Files checked and joind together.
+//
+// Revision 1.3 2001/06/01 22:28:55 mohor
+// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated.
+//
+//
+
+module eth_clockgen(Clk, Reset, Divider, MdcEn, MdcEn_n, Mdc);
+
+//parameter Tp=1;
+
+input Clk; // Input clock (Host clock)
+input Reset; // Reset signal
+input [7:0] Divider; // Divider (input clock will be divided by the Divider[7:0])
+
+output Mdc; // Output clock
+output MdcEn; // Enable signal is asserted for one Clk period before Mdc rises.
+output MdcEn_n; // Enable signal is asserted for one Clk period before Mdc falls.
+
+reg Mdc;
+reg [7:0] Counter;
+
+wire CountEq0;
+wire [7:0] CounterPreset;
+wire [7:0] TempDivider;
+
+
+assign TempDivider[7:0] = (Divider[7:0]<2)? 8'h02 : Divider[7:0]; // If smaller than 2
+assign CounterPreset[7:0] = (TempDivider[7:0]>>1) -1; // We are counting half of period
+
+
+// Counter counts half period
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ Counter[7:0] <= 8'h1;
+ else
+ begin
+ if(CountEq0)
+ begin
+ Counter[7:0] <= CounterPreset[7:0];
+ end
+ else
+ Counter[7:0] <= Counter - 8'h1;
+ end
+end
+
+
+// Mdc is asserted every other half period
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ Mdc <= 1'b0;
+ else
+ begin
+ if(CountEq0)
+ Mdc <= ~Mdc;
+ end
+end
+
+
+assign CountEq0 = Counter == 8'h0;
+assign MdcEn = CountEq0 & ~Mdc;
+assign MdcEn_n = CountEq0 & Mdc;
+
+endmodule
+
+
diff --git a/usrp2/fpga/eth/rtl/verilog/miim/eth_outputcontrol.v b/usrp2/fpga/eth/rtl/verilog/miim/eth_outputcontrol.v new file mode 100644 index 000000000..3df6c560a --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/miim/eth_outputcontrol.v @@ -0,0 +1,158 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// eth_outputcontrol.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects/ethmac/ ////
+//// ////
+//// Author(s): ////
+//// - Igor Mohor (igorM@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: eth_outputcontrol.v,v $
+// Revision 1.2 2005/12/13 12:54:49 maverickist
+// first simulation passed
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+// Revision 1.2 2005/04/27 15:58:46 Administrator
+// no message
+//
+// Revision 1.1.1.1 2004/12/15 06:38:54 Administrator
+// no message
+//
+// Revision 1.4 2002/07/09 20:11:59 mohor
+// Comment removed.
+//
+// Revision 1.3 2002/01/23 10:28:16 mohor
+// Link in the header changed.
+//
+// Revision 1.2 2001/10/19 08:43:51 mohor
+// eth_timescale.v changed to timescale.v This is done because of the
+// simulation of the few cores in a one joined project.
+//
+// Revision 1.1 2001/08/06 14:44:29 mohor
+// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex).
+// Include files fixed to contain no path.
+// File names and module names changed ta have a eth_ prologue in the name.
+// File eth_timescale.v is used to define timescale
+// All pin names on the top module are changed to contain _I, _O or _OE at the end.
+// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O
+// and Mdo_OE. The bidirectional signal must be created on the top level. This
+// is done due to the ASIC tools.
+//
+// Revision 1.1 2001/07/30 21:23:42 mohor
+// Directory structure changed. Files checked and joind together.
+//
+// Revision 1.3 2001/06/01 22:28:56 mohor
+// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated.
+//
+//
+
+module eth_outputcontrol(Clk, Reset, InProgress, ShiftedBit, BitCounter, WriteOp, NoPre, MdcEn_n, Mdo, MdoEn);
+
+input Clk; // Host Clock
+input Reset; // General Reset
+input WriteOp; // Write Operation Latch (When asserted, write operation is in progress)
+input NoPre; // No Preamble (no 32-bit preamble)
+input InProgress; // Operation in progress
+input ShiftedBit; // This bit is output of the shift register and is connected to the Mdo signal
+input [6:0] BitCounter; // Bit Counter
+input MdcEn_n; // MII Management Data Clock Enable signal is asserted for one Clk period before Mdc falls.
+
+output Mdo; // MII Management Data Output
+output MdoEn; // MII Management Data Output Enable
+
+wire SerialEn;
+
+reg MdoEn_2d;
+reg MdoEn_d;
+reg MdoEn;
+
+reg Mdo_2d;
+reg Mdo_d;
+reg Mdo; // MII Management Data Output
+
+
+
+// Generation of the Serial Enable signal (enables the serialization of the data)
+assign SerialEn = WriteOp & InProgress & ( BitCounter>31 | ( ( BitCounter == 0 ) & NoPre ) )
+ | ~WriteOp & InProgress & (( BitCounter>31 & BitCounter<46 ) | ( ( BitCounter == 0 ) & NoPre ));
+
+
+// Generation of the MdoEn signal
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ MdoEn_2d <= 1'b0;
+ MdoEn_d <= 1'b0;
+ MdoEn <= 1'b0;
+ end
+ else
+ begin
+ if(MdcEn_n)
+ begin
+ MdoEn_2d <= SerialEn | InProgress & BitCounter<32;
+ MdoEn_d <= MdoEn_2d;
+ MdoEn <= MdoEn_d;
+ end
+ end
+end
+
+
+// Generation of the Mdo signal.
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ Mdo_2d <= 1'b0;
+ Mdo_d <= 1'b0;
+ Mdo <= 1'b0;
+ end
+ else
+ begin
+ if(MdcEn_n)
+ begin
+ Mdo_2d <= ~SerialEn & BitCounter<32;
+ Mdo_d <= ShiftedBit | Mdo_2d;
+ Mdo <= Mdo_d;
+ end
+ end
+end
+
+
+
+endmodule
diff --git a/usrp2/fpga/eth/rtl/verilog/miim/eth_shiftreg.v b/usrp2/fpga/eth/rtl/verilog/miim/eth_shiftreg.v new file mode 100644 index 000000000..0b97bb7bc --- /dev/null +++ b/usrp2/fpga/eth/rtl/verilog/miim/eth_shiftreg.v @@ -0,0 +1,159 @@ +//////////////////////////////////////////////////////////////////////
+//// ////
+//// eth_shiftreg.v ////
+//// ////
+//// This file is part of the Ethernet IP core project ////
+//// http://www.opencores.org/projects/ethmac/ ////
+//// ////
+//// Author(s): ////
+//// - Igor Mohor (igorM@opencores.org) ////
+//// ////
+//// All additional information is avaliable in the Readme.txt ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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: eth_shiftreg.v,v $
+// Revision 1.2 2005/12/13 12:54:49 maverickist
+// first simulation passed
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+// Revision 1.2 2005/04/27 15:58:47 Administrator
+// no message
+//
+// Revision 1.1.1.1 2004/12/15 06:38:54 Administrator
+// no message
+//
+// Revision 1.5 2002/08/14 18:16:59 mohor
+// LinkFail signal was not latching appropriate bit.
+//
+// Revision 1.4 2002/03/02 21:06:01 mohor
+// LinkFail signal was not latching appropriate bit.
+//
+// Revision 1.3 2002/01/23 10:28:16 mohor
+// Link in the header changed.
+//
+// Revision 1.2 2001/10/19 08:43:51 mohor
+// eth_timescale.v changed to timescale.v This is done because of the
+// simulation of the few cores in a one joined project.
+//
+// Revision 1.1 2001/08/06 14:44:29 mohor
+// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex).
+// Include files fixed to contain no path.
+// File names and module names changed ta have a eth_ prologue in the name.
+// File eth_timescale.v is used to define timescale
+// All pin names on the top module are changed to contain _I, _O or _OE at the end.
+// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O
+// and Mdo_OE. The bidirectional signal must be created on the top level. This
+// is done due to the ASIC tools.
+//
+// Revision 1.1 2001/07/30 21:23:42 mohor
+// Directory structure changed. Files checked and joind together.
+//
+// Revision 1.3 2001/06/01 22:28:56 mohor
+// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated.
+//
+//
+
+module eth_shiftreg(Clk, Reset, MdcEn_n, Mdi, Fiad, Rgad, CtrlData, WriteOp, ByteSelect,
+ LatchByte, ShiftedBit, Prsd, LinkFail);
+
+
+input Clk; // Input clock (Host clock)
+input Reset; // Reset signal
+input MdcEn_n; // Enable signal is asserted for one Clk period before Mdc falls.
+input Mdi; // MII input data
+input [4:0] Fiad; // PHY address
+input [4:0] Rgad; // Register address (within the selected PHY)
+input [15:0]CtrlData; // Control data (data to be written to the PHY)
+input WriteOp; // The current operation is a PHY register write operation
+input [3:0] ByteSelect; // Byte select
+input [1:0] LatchByte; // Byte select for latching (read operation)
+
+output ShiftedBit; // Bit shifted out of the shift register
+output[15:0]Prsd; // Read Status Data (data read from the PHY)
+output LinkFail; // Link Integrity Signal
+
+reg [7:0] ShiftReg; // Shift register for shifting the data in and out
+reg [15:0]Prsd;
+reg LinkFail;
+
+
+
+
+// ShiftReg[7:0] :: Shift Register Data
+always @ (posedge Clk or posedge Reset)
+begin
+ if(Reset)
+ begin
+ ShiftReg[7:0] <= 8'h0;
+ Prsd[15:0] <= 16'h0;
+ LinkFail <= 1'b0;
+ end
+ else
+ begin
+ if(MdcEn_n)
+ begin
+ if(|ByteSelect)
+ begin
+ case (ByteSelect[3:0])
+ 4'h1 : ShiftReg[7:0] <= {2'b01, ~WriteOp, WriteOp, Fiad[4:1]};
+ 4'h2 : ShiftReg[7:0] <= {Fiad[0], Rgad[4:0], 2'b10};
+ 4'h4 : ShiftReg[7:0] <= CtrlData[15:8];
+ 4'h8 : ShiftReg[7:0] <= CtrlData[7:0];
+ default : ShiftReg[7:0] <= 8'h0;
+ endcase
+ end
+ else
+ begin
+ ShiftReg[7:0] <= {ShiftReg[6:0], Mdi};
+ if(LatchByte[0])
+ begin
+ Prsd[7:0] <= {ShiftReg[6:0], Mdi};
+ if(Rgad == 5'h01)
+ LinkFail <= ~ShiftReg[1]; // this is bit [2], because it is not shifted yet
+ end
+ else
+ begin
+ if(LatchByte[1])
+ Prsd[15:8] <= {ShiftReg[6:0], Mdi};
+ end
+ end
+ end
+ end
+end
+
+
+assign ShiftedBit = ShiftReg[7];
+
+
+endmodule
diff --git a/usrp2/fpga/eth/rx_prot_engine.v b/usrp2/fpga/eth/rx_prot_engine.v new file mode 100644 index 000000000..d34f168d7 --- /dev/null +++ b/usrp2/fpga/eth/rx_prot_engine.v @@ -0,0 +1,156 @@ + +module rx_prot_engine + #(parameter FIFO_SIZE=11) + (input clk, input rst, + + input Rx_mac_ra, + output Rx_mac_rd, + input [31:0] Rx_mac_data, + input [1:0] Rx_mac_BE, + input Rx_mac_pa, + input Rx_mac_sop, + input Rx_mac_eop, + input Rx_mac_err, + + output [31:0] wr_dat_o, + output wr_write_o, + output wr_done_o, + output wr_error_o, + input wr_ready_i, + input wr_full_i, + output wr_flag_o, + + input set_stb, + input [7:0] set_addr, + input [31:0] set_data, + + output [15:0] rx_fifo_status, + output reg [7:0] rx_seqnum, + output reg [7:0] rx_channel, + output [7:0] rx_flags + ); + + wire read, write, full, empty; + wire eop_i, err_i, eop_o, err_o, flag_i, sop_i, flag_o, sop_o; + wire [31:0] dat_i, dat_o; + reg xfer_active; + + wire [3:0] hdr_adr; + wire [31:0] hdr_dat; + + header_ram #(.REGNUM(48),.WIDTH(32)) rx_header_ram + (.clk(clk),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .addr(hdr_adr),.q(hdr_dat)); + + // Buffer interface side + always @(posedge clk) + if(rst) + xfer_active <= 0; + else if(wr_ready_i & ~empty) + xfer_active <= 1; + else if(eop_o | err_o | wr_full_i) + xfer_active <= 0; + + assign wr_done_o = eop_o & wr_write_o; + assign wr_error_o = err_o & wr_write_o; + assign wr_dat_o = dat_o; + assign wr_write_o = xfer_active & ~empty; + assign read = wr_write_o; + + // FIFO in the middle + cascadefifo2 #(.WIDTH(36),.SIZE(11)) rx_prot_fifo + (.clk(clk),.rst(rst), + .datain({flag_i,sop_i,eop_i,err_i,dat_i}),.write(write),.full(full), + .dataout({flag_o,sop_o,eop_o,err_o,dat_o}),.read(read),.empty(empty), + .clear(0),.fifo_space(rx_fifo_status)); + + // MAC side + localparam ETH_TYPE = 16'hBEEF; + + reg [2:0] prot_state; + localparam PROT_IDLE = 0; + localparam PROT_HDR1 = 1; + localparam PROT_HDR2 = 2; + localparam PROT_HDR3 = 3; + localparam PROT_HDR4 = 4; + localparam PROT_HDR5 = 5; + localparam PROT_PKT = 6; + + // Things to control: flag_i, sop_i, eop_i, err_i, dat_i, write, Rx_mac_rd + // Inputs to SM: Rx_mac_sop, Rx_mac_eop, Rx_mac_ra, Rx_mac_pa, + // Rx_mac_BE, Rx_mac_err, full + + reg flag; + assign dat_i = Rx_mac_data; + assign sop_i = Rx_mac_sop; + assign eop_i = Rx_mac_eop; + assign err_i = Rx_mac_err; + assign flag_i = flag; + assign wr_flag_o = flag_o; + assign Rx_mac_rd = (prot_state != PROT_IDLE) && (~full|~Rx_mac_pa); + assign write = (prot_state != PROT_IDLE) && ~full && Rx_mac_pa; + + assign hdr_adr = {1'b0,prot_state[2:0]}; + + wire [7:0] rx_seqnum_p1 = rx_seqnum + 1; + + always @(posedge clk) + if(rst) + begin + prot_state <= PROT_IDLE; + flag <= 0; + end + else if(prot_state == PROT_IDLE) + begin + flag <= 0; + if(Rx_mac_ra) + prot_state <= PROT_HDR1; + end + else if(write) + case(prot_state) + PROT_HDR1 : + begin + prot_state <= PROT_HDR2; + if(hdr_dat != Rx_mac_data) + flag <= 1; + end + PROT_HDR2 : + begin + prot_state <= PROT_HDR3; + if(hdr_dat != Rx_mac_data) + flag <= 1; + end + PROT_HDR3 : + begin + prot_state <= PROT_HDR4; + if(hdr_dat != Rx_mac_data) + flag <= 1; + end + PROT_HDR4 : + begin + prot_state <= PROT_HDR5; + if(hdr_dat[31:16] != Rx_mac_data[31:16]) + flag <= 1; + rx_channel <= hdr_dat[15:8]; + end + PROT_HDR5 : + begin + prot_state <= PROT_PKT; + if((rx_seqnum_p1) != Rx_mac_data[15:8]) + flag <= 1; + end + PROT_PKT : + if(Rx_mac_eop | Rx_mac_err) + prot_state <= PROT_IDLE; + endcase // case(prot_state) + + always @(posedge clk) + if(rst) + rx_seqnum <= 8'hFF; + else if(set_stb & (set_addr == 54)) + rx_seqnum <= set_data[7:0]; + else if(write & (prot_state == PROT_HDR5) & ((rx_seqnum_p1) == Rx_mac_data[15:8]) & ~flag) + rx_seqnum <= rx_seqnum + 1; + + // Error cases -- Rx_mac_error, BE != 0 +endmodule // rx_prot_engine diff --git a/usrp2/fpga/eth/tx_prot_engine.v b/usrp2/fpga/eth/tx_prot_engine.v new file mode 100644 index 000000000..894d74a11 --- /dev/null +++ b/usrp2/fpga/eth/tx_prot_engine.v @@ -0,0 +1,144 @@ + +module tx_prot_engine + (input clk, input rst, + + // To MAC + input Tx_mac_wa, + output Tx_mac_wr, + output [31:0] Tx_mac_data, + output [1:0] Tx_mac_BE, + output Tx_mac_sop, + output Tx_mac_eop, + + // To buffer interface + input [31:0] rd_dat_i, + output rd_read_o, + output rd_done_o, + output rd_error_o, + input rd_sop_i, + input rd_eop_i, + + // To control + input set_stb, + input [7:0] set_addr, + input [31:0] set_data, + + // Protocol Stuff + input [15:0] rx_fifo_status, + input [7:0] rx_seqnum + //input [7:0] tx_channel, + //input [7:0] tx_flags + ); + + wire [3:0] hdr_adr; + wire [31:0] hdr_dat; + wire [7:0] tx_channel; + + header_ram #(.REGNUM(32),.WIDTH(32)) tx_header_ram + (.clk(clk),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .addr(hdr_adr),.q(hdr_dat)); + + setting_reg #(.my_addr(32)) sr_channel + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data), + .out(tx_channel),.changed()); + + // Might as well use a shortfifo here since they are basically free + wire empty, full, sfifo_write, sfifo_read; + wire [33:0] sfifo_in, sfifo_out; + + shortfifo #(.WIDTH(34)) txmac_sfifo + (.clk(clk),.rst(rst),.clear(0), + .datain(sfifo_in),.write(sfifo_write),.full(full), + .dataout(sfifo_out),.read(sfifo_read),.empty(empty)); + + // MAC side signals + // Inputs -- Tx_mac_wa, sfifo_out, empty + // outputs -- sfifo_read, Tx_mac_data, Tx_mac_wr, Tx_mac_BE, Tx_mac_sop, Tx_mac_eop + + // We are allowed to do one more write after we are told the FIFO is full + // This allows us to register the _wa signal and speed up timing. + reg tx_mac_wa_d1; + always @(posedge clk) + tx_mac_wa_d1 <= Tx_mac_wa; + + reg [2:0] prot_state; + localparam PROT_IDLE = 0; + localparam PROT_HDR1 = 1; + localparam PROT_HDR2 = 2; + localparam PROT_HDR3 = 3; + localparam PROT_HDR4 = 4; + localparam PROT_HDR5 = 5; + localparam PROT_PKT = 6; + + reg [7:0] tx_seqnum; + reg all_match; + always @(posedge clk) + if(rst) + tx_seqnum <= 0; + else if(set_stb & (set_addr == 36)) + tx_seqnum <= set_data[7:0]; + else if(tx_mac_wa_d1 & all_match & (prot_state == PROT_HDR5)) + tx_seqnum <= tx_seqnum + 1; + + always @(posedge clk) + if(rst) + prot_state <= PROT_IDLE; + else + if(tx_mac_wa_d1 & ~empty) + case(prot_state) + PROT_IDLE : + prot_state <= PROT_HDR1; + PROT_HDR1 : + prot_state <= PROT_HDR2; + PROT_HDR2 : + prot_state <= PROT_HDR3; + PROT_HDR3 : + prot_state <= PROT_HDR4; + PROT_HDR4 : + prot_state <= PROT_HDR5; + PROT_HDR5 : + prot_state <= PROT_PKT; + PROT_PKT : + if(sfifo_out[32] & ~empty) + prot_state <= PROT_IDLE; + default : + prot_state <= PROT_IDLE; + endcase // case(prot_state) + + assign hdr_adr = {1'b0,prot_state}; + wire match = (hdr_dat == sfifo_out[31:0]); + always @(posedge clk) + if(prot_state == PROT_IDLE) + all_match <= 1; + else if(tx_mac_wa_d1 & ~empty & + ((prot_state==PROT_HDR1)|(prot_state==PROT_HDR2)|(prot_state==PROT_HDR3))) + all_match <= all_match & match; + + localparam ETH_TYPE = 16'hBEEF; + assign Tx_mac_data = + ((prot_state == PROT_HDR5) & all_match) ? {rx_fifo_status,tx_seqnum,rx_seqnum} : + sfifo_out[31:0]; + assign sfifo_read = (prot_state != PROT_IDLE) & ~empty & tx_mac_wa_d1; + assign Tx_mac_wr = sfifo_read; + assign Tx_mac_BE = 0; // Since we only deal with packets that are multiples of 32 bits long + assign Tx_mac_sop = sfifo_out[33]; + assign Tx_mac_eop = sfifo_out[32]; + + // BUFFER side signals + reg xfer_active; + always @(posedge clk) + if(rst) + xfer_active <= 0; + else if(rd_eop_i & ~full) + xfer_active <= 0; + else if(rd_sop_i) + xfer_active <= 1; + + assign sfifo_in = {rd_sop_i, rd_eop_i, rd_dat_i}; + assign sfifo_write = xfer_active & ~full; + + assign rd_read_o = sfifo_write; + assign rd_done_o = 0; // Always send everything we're given? + assign rd_error_o = 0; // No possible error situations? + +endmodule // tx_prot_engine |