URL
https://opencores.org/ocsvn/ethmac/ethmac/trunk
Subversion Repositories ethmac
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 40 to Rev 41
- ↔ Reverse comparison
Rev 40 → Rev 41
/trunk/bench/verilog/tb_eth_top.v
3,7 → 3,7
//// tb_eth_top.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/cores/ethmac/ //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// //// |
//// Author(s): //// |
//// - Igor Mohor (igorM@opencores.org) //// |
41,6 → 41,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.6 2001/12/08 12:36:00 mohor |
// TX_BD_NUM register added instead of the RB_BD_ADDR. |
// |
// Revision 1.5 2001/10/19 11:24:04 mohor |
// Number of addresses (wb_adr_i) minimized. |
// |
95,14 → 98,28
reg WB_WE_I; |
reg WB_CYC_I; |
reg WB_STB_I; |
reg [1:0] WB_ACK_I; |
|
wire [31:0] WB_DAT_O; |
wire WB_ACK_O; |
wire WB_ERR_O; |
reg [1:0] WB_ACK_I; |
|
`ifdef WISHBONE_DMA |
wire [1:0] WB_REQ_O; |
wire [1:0] WB_ND_O; |
wire WB_RD_O; |
`else |
// WISHBONE master |
wire [31:0] m_wb_adr_o; |
wire [3:0] m_wb_sel_o; |
wire m_wb_we_o; |
reg [31:0] m_wb_dat_i; |
wire [31:0] m_wb_dat_o; |
wire m_wb_cyc_o; |
wire m_wb_stb_o; |
reg m_wb_ack_i; |
reg m_wb_err_i; |
`endif |
|
reg MTxClk; |
wire [3:0] MTxD; |
115,6 → 132,7
reg MRxErr; |
reg MColl; |
reg MCrs; |
reg RxAbort; |
|
reg Mdi_I; |
wire Mdo_O; |
130,8 → 148,12
reg [9:0] TxBDIndex; |
reg [9:0] RxBDIndex; |
|
`ifdef WISHBONE_DMA |
`else |
integer mcd1; |
integer mcd2; |
`endif |
|
|
// Connecting Ethernet top module |
|
eth_top ethtop |
141,8 → 163,16
|
// WISHBONE slave |
.wb_adr_i(WB_ADR_I[11:2]), .wb_sel_i(WB_SEL_I), .wb_we_i(WB_WE_I), .wb_cyc_i(WB_CYC_I), |
.wb_stb_i(WB_STB_I), .wb_ack_o(WB_ACK_O), .wb_err_o(WB_ERR_O), .wb_req_o(WB_REQ_O), |
.wb_ack_i(WB_ACK_I), .wb_nd_o(WB_ND_O), .wb_rd_o(WB_RD_O), |
.wb_stb_i(WB_STB_I), .wb_ack_o(WB_ACK_O), .wb_err_o(WB_ERR_O), .wb_ack_i(WB_ACK_I), |
|
`ifdef WISHBONE_DMA |
.wb_req_o(WB_REQ_O), .wb_nd_o(WB_ND_O), .wb_rd_o(WB_RD_O), |
`else |
// WISHBONE master |
.m_wb_adr_o(m_wb_adr_o), .m_wb_sel_o(m_wb_sel_o), .m_wb_we_o(m_wb_we_o), .m_wb_dat_i(m_wb_dat_i), |
.m_wb_dat_o(m_wb_dat_o), .m_wb_cyc_o(m_wb_cyc_o), .m_wb_stb_o(m_wb_stb_o), .m_wb_ack_i(m_wb_ack_i), |
.m_wb_err_i(m_wb_err_i), |
`endif |
|
//TX |
.mtx_clk_pad_i(MTxClk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr), |
150,6 → 180,8
//RX |
.mrx_clk_pad_i(MRxClk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr), |
.mcoll_pad_i(MColl), .mcrs_pad_i(MCrs), |
.RxAbort(RxAbort), // igor !!! Ta se mora preseliti da bo prisel iz enega izmed modulov. Tu je le zaradi |
// testiranja. Pove, kdaj adresa ni ustrezala in se paketi sklirajo, stevci pa resetirajo. |
|
// MIIM |
.mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoen_o(Mdo_OE), |
172,7 → 204,13
WB_WE_I = 1'b0; |
WB_CYC_I = 1'b0; |
WB_STB_I = 1'b0; |
|
`ifdef WISHBONE_DMA |
WB_ACK_I = 2'h0; |
`else |
m_wb_ack_i = 0; |
m_wb_err_i = 0; |
`endif |
MTxClk = 1'b0; |
MRxClk = 1'b0; |
MRxD = 4'h0; |
180,6 → 218,7
MRxErr = 1'b0; |
MColl = 1'b0; |
MCrs = 1'b0; |
RxAbort = 1'b0; |
Mdi_I = 1'b0; |
|
WishboneBusy = 1'b0; |
191,10 → 230,13
// Reset pulse |
initial |
begin |
`ifdef WISHBONE_DMA |
`else |
mcd1 = $fopen("ethernet_tx.log"); |
mcd2 = $fopen("ethernet_rx.log"); |
`endif |
WB_RST_I = 1'b1; |
GSR = 1'b1; |
WB_RST_I = 1'b1; |
#100 WB_RST_I = 1'b1; |
GSR = 1'b1; |
#100 WB_RST_I = 1'b0; |
GSR = 1'b0; |
#100 StartTB = 1'b1; |
208,11 → 250,14
// Generating WB_CLK_I clock |
always |
begin |
// forever #2.5 WB_CLK_I = ~WB_CLK_I; // 2*2.5 ns -> 200.0 MHz |
// forever #5 WB_CLK_I = ~WB_CLK_I; // 2*5 ns -> 100.0 MHz |
// forever #10 WB_CLK_I = ~WB_CLK_I; // 2*10 ns -> 50.0 MHz |
forever #15 WB_CLK_I = ~WB_CLK_I; // 2*10 ns -> 33.3 MHz |
// forever #18 WB_CLK_I = ~WB_CLK_I; // 2*18 ns -> 27.7 MHz |
// forever #100 WB_CLK_I = ~WB_CLK_I; |
// forever #25 WB_CLK_I = ~WB_CLK_I; // 2*25 ns -> 20.0 MHz |
// forever #50 WB_CLK_I = ~WB_CLK_I; // 2*50 ns -> 10.0 MHz |
// forever #55 WB_CLK_I = ~WB_CLK_I; // 2*55 ns -> 9.1 MHz |
end |
|
// Generating MTxClk clock |
229,8 → 274,7
// #16 forever #250 MRxClk = ~MRxClk; |
end |
|
|
|
`ifdef WISHBONE_DMA |
initial |
begin |
wait(StartTB); // Start of testbench |
649,6 → 693,373
end |
endtask |
|
`else // No WISHBONE_DMA |
|
initial |
begin |
wait(StartTB); // Start of testbench |
|
WishboneWrite(32'h00000800, {26'h0, `ETH_MODER_ADR<<2}); // r_Rst = 1 |
WishboneWrite(32'h00000000, {26'h0, `ETH_MODER_ADR<<2}); // r_Rst = 0 |
WishboneWrite(32'h00000080, {26'h0, `ETH_TX_BD_NUM_ADR<<2}); // r_RxBDAddress = 0x80 |
|
WishboneWrite(32'h0002A443, {26'h0, `ETH_MODER_ADR<<2}); // RxEn, Txen, FullD, CrcEn, Pad, DmaEn, r_IFG |
|
WishboneWrite(32'h00000004, {26'h0, `ETH_CTRLMODER_ADR<<2}); //r_TxFlow = 1 |
|
|
SendPacket(16'h0010, 1'b0); |
SendPacket(16'h0011, 1'b0); |
SendPacket(16'h0012, 1'b0); |
SendPacket(16'h0013, 1'b0); |
SendPacket(16'h0014, 1'b0); |
|
SendPacket(16'h0030, 1'b0); |
SendPacket(16'h0031, 1'b0); |
SendPacket(16'h0032, 1'b0); |
SendPacket(16'h0033, 1'b0); |
SendPacket(16'h0025, 1'b0); |
SendPacket(16'h0045, 1'b0); |
SendPacket(16'h0025, 1'b0); |
SendPacket(16'h0017, 1'b0); |
|
// ReceivePacket(16'h0012, 1'b1, 1'b0); // Initializes RxBD and then Sends a control packet on the MRxD[3:0] signals. |
ReceivePacket(16'h0015, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
ReceivePacket(16'h0016, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
ReceivePacket(16'h0017, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
ReceivePacket(16'h0018, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
|
repeat(5000) @ (posedge MRxClk); // Waiting some time for all accesses to finish before reading out the statuses. |
|
WishboneRead({26'h0, `ETH_MODER_ADR}); // Read from MODER register |
|
WishboneRead({24'h04, (8'h0<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h1<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h2<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h3<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h4<<2)}); // Read from TxBD register |
|
|
WishboneRead({22'h01, (10'h80<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h81<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h82<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h83<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h84<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h85<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h86<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h87<<2)}); // Read from RxBD register |
|
#100000 $stop; |
end |
|
//integer ijk; |
|
//initial |
//ijk = 0; // for stoping generation of the m_wb_ack_i signal at the right moment so we get underrun |
|
// Answering to master Wishbone requests |
always @ (posedge WB_CLK_I) |
begin |
if(m_wb_cyc_o & m_wb_stb_o) // Add valid address range |
begin |
repeat(3) @ (posedge WB_CLK_I); |
begin |
// if(ijk==41) |
// begin |
// repeat(1000) @ (posedge WB_CLK_I); |
// end |
// else |
m_wb_ack_i <=#Tp 1'b1; |
if(~m_wb_we_o) |
begin |
#Tp m_wb_dat_i = m_wb_adr_o + 1'b1; // For easier following of the data |
$fdisplay(mcd1, "(%0t) master read (0x%0x) = 0x%0x", $time, m_wb_adr_o, m_wb_dat_i); |
// ijk = ijk + 1; |
end |
else |
$fdisplay(mcd2, "(%0t) master write (0x%0x) = 0x%0x", $time, m_wb_adr_o, m_wb_dat_o); |
end |
@ (posedge WB_CLK_I); |
m_wb_ack_i <=#Tp 1'b0; |
end |
end |
|
// Generating error |
always @ (posedge WB_CLK_I) |
begin |
if(m_wb_cyc_o & m_wb_stb_o & ~(&m_wb_sel_o)) // Add false address range |
m_wb_err_i <=#Tp 1'b1; |
end |
|
always @ (posedge WB_CLK_I) |
if(tb_eth_top.ethtop.wishbone.RxStatusWrite) |
$fdisplay(mcd2, ""); // newline added |
|
task WishboneWrite; |
input [31:0] Data; |
input [31:0] Address; |
integer ii; |
|
begin |
wait (~WishboneBusy); |
WishboneBusy = 1; |
@ (posedge WB_CLK_I); |
#1; |
WB_ADR_I = Address; |
WB_DAT_I = Data; |
WB_WE_I = 1'b1; |
WB_CYC_I = 1'b1; |
WB_STB_I = 1'b1; |
WB_SEL_I = 4'hf; |
|
|
wait(WB_ACK_O); // waiting for acknowledge response |
|
// Writing information about the access to the screen |
@ (posedge WB_CLK_I); |
if(~Address[11] & ~Address[10]) |
$write("\n(%0t) Write to register (Data: 0x%x, Reg. Addr: 0x%0x)", $time, Data, Address); |
else |
if(~Address[11] & Address[10]) |
if(Address[9:2] < tb_eth_top.ethtop.r_TxBDNum) |
begin |
$write("\n(%0t) Write to TxBD (Data: 0x%x, TxBD Addr: 0x%0x)", $time, Data, Address); |
if(Data[9]) |
$write("(%0t) Send Control packet (PAUSE = 0x%0h)\n", $time, Data[31:16]); |
end |
else |
$write("\n(%0t) Write to RxBD (Data: 0x%x, RxBD Addr: 0x%0x)", $time, Data, Address); |
else |
$write("\n(%0t) WB write ?????????????? Data: 0x%x Addr: 0x%0x", $time, Data, Address); |
#1; |
WB_ADR_I = 32'hx; |
WB_DAT_I = 32'hx; |
WB_WE_I = 1'bx; |
WB_CYC_I = 1'b0; |
WB_STB_I = 1'b0; |
WB_SEL_I = 4'hx; |
#5 WishboneBusy = 0; |
end |
endtask |
|
|
task WishboneRead; |
input [31:0] Address; |
|
begin |
wait (~WishboneBusy); |
WishboneBusy = 1; |
@ (posedge WB_CLK_I); |
#1; |
WB_ADR_I = Address; |
WB_WE_I = 1'b0; |
WB_CYC_I = 1'b1; |
WB_STB_I = 1'b1; |
WB_SEL_I = 4'hf; |
|
wait(WB_ACK_O); // waiting for acknowledge response |
@ (posedge WB_CLK_I); |
|
if(~Address[11] & ~Address[10]) |
$write("\n(%0t) Read from register (Data: 0x%x, Reg. Addr: 0x%0x)", $time, WB_DAT_O, Address); |
else |
if(~Address[11] & Address[10]) |
if(Address[9:2] < tb_eth_top.ethtop.r_TxBDNum) |
begin |
$write("\n(%0t) Read from TxBD (Data: 0x%x, TxBD Addr: 0x%0x)", $time, WB_DAT_O, Address); |
end |
else |
$write("\n(%0t) Read from RxBD (Data: 0x%x, RxBD Addr: 0x%0x)", $time, WB_DAT_O, Address); |
else |
$write("\n(%0t) WB read ????????? Data: 0x%x Addr: 0x%0x", $time, WB_DAT_O, Address); |
#1; |
WB_ADR_I = 32'hx; |
WB_WE_I = 1'bx; |
WB_CYC_I = 1'b0; |
WB_STB_I = 1'b0; |
WB_SEL_I = 4'hx; |
#5 WishboneBusy = 0; |
end |
endtask |
|
|
|
|
task SendPacket; |
input [15:0] Length; |
input ControlFrame; |
reg Wrap; |
reg [31:0] TempAddr; |
reg [31:0] TempData; |
|
begin |
// if(TxBDIndex == 6) // Only 3 buffer descriptors are used |
// Wrap = 1'b1; |
// else |
Wrap = 1'b0; // At the moment no wrap bit is set |
|
// Writing buffer pointer |
TempAddr = {22'h01, ((TxBDIndex + 1'b1)<<2)}; |
TempData = 32'h78563411; |
WishboneWrite(TempData, TempAddr); // buffer pointer |
|
|
TempAddr = {22'h01, (TxBDIndex<<2)}; // igor !!! zbrisi spodnjo vrstico |
// TempAddr = {22'h01, 10'b1010010100}; |
|
TempData = {Length[15:0], 1'b1, 1'b0, Wrap, 3'h0, ControlFrame, 1'b0, TxBDIndex[7:0]}; // Ready and Wrap = 1 |
|
#1; |
// if(TxBDIndex == 6) // Only 4 buffer descriptors are used |
// TxBDIndex = 0; |
// else |
TxBDIndex = TxBDIndex + 2; |
|
WishboneWrite(TempData, TempAddr); // Writing status to TxBD |
end |
endtask |
|
|
|
task ReceivePacket; // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
input [15:0] LengthRx; |
input RxControlFrame; |
input Abort; |
reg WrapRx; |
reg [31:0] TempRxAddr; |
reg [31:0] TempRxData; |
reg abc; |
begin |
// if(RxBDIndex == 6) // Only 3 buffer descriptors are used |
// WrapRx = 1'b1; |
// else |
WrapRx = 1'b0; |
|
TempRxAddr = {22'h01, ((tb_eth_top.ethtop.r_TxBDNum + RxBDIndex + 1'b1)<<2)}; |
TempRxData = 32'h73507350 + RxBDIndex; |
WishboneWrite(TempRxData, TempRxAddr); // Writing Rx pointer |
|
|
TempRxAddr = {22'h01, ((tb_eth_top.ethtop.r_TxBDNum + RxBDIndex)<<2)}; |
// TempRxData = {LengthRx[15:0], 1'b1, 1'b0, WrapRx, 5'h0, RxBDIndex[7:0]}; // Ready and WrapRx = 1 or 0 |
TempRxData = {16'h0, 1'b1, 1'b0, WrapRx, 5'h0, RxBDIndex[7:0]}; // Ready and WrapRx = 1 or 0 |
|
#1; |
// if(RxBDIndex == 6) // Only 4 buffer descriptors are used |
// RxBDIndex = 0; |
// else |
RxBDIndex = RxBDIndex + 2; |
|
abc=1; |
WishboneWrite(TempRxData, TempRxAddr); // Writing status to RxBD |
abc=0; |
|
begin |
#200; |
if(RxControlFrame) |
GetControlDataOnMRxD(LengthRx); // LengthRx = PAUSE timer value. |
else |
GetDataOnMRxD(LengthRx, Abort); // LengthRx bytes is comming on MRxD[3:0] signals |
end |
|
end |
endtask |
|
|
task GetDataOnMRxD; |
input [15:0] Len; |
input abort; |
integer tt; |
|
begin |
@ (posedge MRxClk); |
MRxDV=1'b1; |
|
for(tt=0; tt<15; tt=tt+1) |
begin |
MRxD=4'h5; // preamble |
@ (posedge MRxClk); |
end |
MRxD=4'hd; // SFD |
|
for(tt=1; tt<(Len+1); tt=tt+1) |
begin |
@ (posedge MRxClk); |
MRxD=tt[3:0]; |
if(tt==9) |
RxAbort<=#1 abort; |
@ (posedge MRxClk); |
MRxD=tt[7:4]; |
RxAbort<=#1 0; |
end |
@ (posedge MRxClk); |
MRxDV=1'b0; |
end |
endtask |
|
|
task GetControlDataOnMRxD; |
input [15:0] Timer; |
reg [127:0] Packet; |
reg [127:0] Data; |
reg [31:0] Crc; |
integer tt; |
|
begin |
Packet = 128'h10082C000010_deadbeef0013_8880_0010; // 0180c2000001 + 8808 + 0001 |
Crc = 32'h6014fe08; // not a correct value |
|
@ (posedge MRxClk); |
MRxDV=1'b1; |
|
for(tt=0; tt<15; tt=tt+1) |
begin |
MRxD=4'h5; // preamble |
@ (posedge MRxClk); |
end |
MRxD=4'hd; // SFD |
|
for(tt=0; tt<32; tt=tt+1) |
begin |
Data = Packet << (tt*4); |
@ (posedge MRxClk); |
MRxD=Data[127:124]; |
end |
|
for(tt=0; tt<2; tt=tt+1) // timer |
begin |
Data[15:0] = Timer << (tt*8); |
@ (posedge MRxClk); |
MRxD=Data[11:8]; |
@ (posedge MRxClk); |
MRxD=Data[15:12]; |
end |
|
for(tt=0; tt<42; tt=tt+1) // padding |
begin |
Data[7:0] = 8'h0; |
@ (posedge MRxClk); |
MRxD=Data[3:0]; |
@ (posedge MRxClk); |
MRxD=Data[3:0]; |
end |
|
for(tt=0; tt<4; tt=tt+1) // crc |
begin |
Data[31:0] = Crc << (tt*8); |
@ (posedge MRxClk); |
MRxD=Data[27:24]; |
@ (posedge MRxClk); |
MRxD=Data[31:28]; |
end |
|
|
|
@ (posedge MRxClk); |
MRxDV=1'b0; |
end |
endtask |
`endif |
|
|
endmodule |
/trunk/rtl/verilog/eth_wishbone.v
41,6 → 41,11
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/05 16:44:39 mohor |
// Both rx and tx part are finished. Tested with wb_clk_i between 10 and 200 |
// MHz. Statuses, overrun, control frame transmission and reception still need |
// to be fixed. |
// |
// Revision 1.2 2002/02/01 12:46:51 mohor |
// Tx part finished. TxStatus needs to be fixed. Pause request needs to be |
// added. |
327,35 → 332,12
`endif |
|
|
|
|
// Generic synchronous two-port RAM interface |
/* |
generic_tpram #(8, 32) i_generic_tpram |
( |
.clk_a(WB_CLK_I), .rst_a(Reset), .ce_a(1'b1), .we_a(BDWrite), |
.oe_a(EnableRAM), .addr_a(WB_ADR_I[9:2]), .di_a(WB_DAT_I), .do_a(WB_BDDataOut), |
|
.clk_b(WB_CLK_I), .rst_b(Reset), .ce_b(EnableRAM), .we_b(BDStatusWrite), |
.oe_b(EnableRAM), .addr_b(BDAddress[7:0]), .di_b(BDDataIn), .do_b(BDDataOut) |
); |
*/ |
|
|
|
RAMB4_S16 ram1 (.DO(ram_do[15:0]), .ADDR(ram_addr), .DI(ram_di[15:0]), .EN(ram_ce), |
.CLK(WB_CLK_I), .WE(ram_we), .RST(Reset)); |
RAMB4_S16 ram2 (.DO(ram_do[31:16]), .ADDR(ram_addr), .DI(ram_di[31:16]), .EN(ram_ce), |
.CLK(WB_CLK_I), .WE(ram_we), .RST(Reset)); |
|
|
|
/* |
// Generic synchronous single-port RAM interface |
generic_spram #(8, 32) ram ( |
// Generic synchronous single-port RAM interface |
.clk(WB_CLK_I), .rst(Reset), .ce(ram_ce), .we(ram_we), .oe(ram_oe), .addr(ram_addr), .di(ram_di), .do(ram_do) |
); |
*/ |
|
assign ram_ce = 1'b1; |
assign ram_we = BDWrite & WbEn & WbEn_q | TxStatusWrite | RxStatusWrite; |
assign ram_oe = BDRead & WbEn & WbEn_q | TxEn & TxEn_q & (TxBDRead | TxPointerRead) | RxEn & RxEn_q & (RxBDRead | RxPointerRead); // Tu manjka se read kadar se bere RxBD |
1559,7 → 1541,6
wire WriteRxDataToFifo_wb; |
assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync1 & ~WriteRxDataToFifoSync2; |
|
reg RxAbortLatched; |
reg RxAbortSync1; |
reg RxAbortSync2; |
reg RxAbortSyncb1; |
1638,21 → 1619,6
end |
|
|
|
// Generation of the end-of-frame signal |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(Reset) |
RxAbortLatched <=#Tp 1'b0; |
else |
if(RxAbort) |
RxAbortLatched <=#Tp 1'b1; |
else |
if(RxAbortSyncb2 | RxStartFrm) |
RxAbortLatched <=#Tp 1'b0; |
end |
|
|
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(Reset) |
/trunk/rtl/verilog/eth_wishbonedma.v
41,6 → 41,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.10 2002/01/23 10:28:16 mohor |
// Link in the header changed. |
// |
// Revision 1.9 2001/12/05 15:00:16 mohor |
// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors |
// instead of the number of RX descriptors). |
98,7 → 101,7
( |
|
// WISHBONE common |
WB_CLK_I, WB_RST_I, WB_DAT_I, WB_DAT_O, |
WB_CLK_I, Reset, WB_DAT_I, WB_DAT_O, |
|
// WISHBONE slave |
WB_ADR_I, WB_SEL_I, WB_WE_I, WB_ACK_O, |
127,7 → 130,7
|
// WISHBONE common |
input WB_CLK_I; // WISHBONE clock |
input WB_RST_I; // WISHBONE reset |
input Reset; // WISHBONE reset |
input [31:0] WB_DAT_I; // WISHBONE data input |
output [31:0] WB_DAT_O; // WISHBONE data output |
|
262,7 → 265,7
reg GotDataSync1; |
reg GotDataSync2; |
wire TPauseRqSync2; |
wire GotDataSync3; |
wire GotDataSync3; |
reg GotData; |
reg SyncGetNewTxData_wb1; |
reg SyncGetNewTxData_wb2; |
269,7 → 272,7
reg SyncGetNewTxData_wb3; |
reg TxDoneSync1; |
reg TxDoneSync2; |
wire TxDoneSync3; |
wire TxDoneSync3; |
reg TxRetrySync1; |
reg TxRetrySync2; |
wire TxRetrySync3; |
395,9 → 398,9
|
|
reg EnableRAM; |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
EnableRAM <=#Tp 1'b0; |
else |
if(BDWe) |
410,18 → 413,18
// Generic synchronous two-port RAM interface |
generic_tpram #(8, 32) i_generic_tpram |
( |
.clk_a(WB_CLK_I), .rst_a(WB_RST_I), .ce_a(1'b1), .we_a(BDWe), |
.clk_a(WB_CLK_I), .rst_a(Reset), .ce_a(1'b1), .we_a(BDWe), |
.oe_a(EnableRAM), .addr_a(WB_ADR_I[9:2]), .di_a(WB_DAT_I), .do_a(WB_BDDataOut), |
|
.clk_b(WB_CLK_I), .rst_b(WB_RST_I), .ce_b(EnableRAM), .we_b(BDStatusWrite), |
.clk_b(WB_CLK_I), .rst_b(Reset), .ce_b(EnableRAM), .we_b(BDStatusWrite), |
.oe_b(EnableRAM), .addr_b(BDAddress[7:0]), .di_b(BDDataIn), .do_b(BDDataOut) |
); |
|
|
// WB_CLK_I is divided by 2. This signal is used for enabling tx and rx operations sequentially |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
Div2 <=#Tp 1'h0; |
else |
Div2 <=#Tp ~Div2; |
434,9 → 437,9
|
|
// Changes for tx occur every second clock. Flop is used for this manner. |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
Flop <=#Tp 1'b0; |
else |
if(TxDone | TxAbort | TxRetry_q) |
448,9 → 451,9
|
|
// Latching READY status of the Tx buffer descriptor |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxBDReady <=#Tp 1'b0; |
else |
if(TxEn & TxBDRead) |
462,9 → 465,9
|
|
// Latching READY status of the Tx buffer descriptor |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
begin |
TxPauseRq <=#Tp 1'b0; |
end |
483,9 → 486,9
// Reading the Tx buffer descriptor |
assign StartTxBDRead = TxEn & ~BlockingTxBDRead & (TxRetry_wb | TxStatusWriteOccured); |
|
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxBDRead <=#Tp 1'b1; |
else |
if(StartTxBDRead) |
503,9 → 506,9
|
|
// Reading data |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxDataRead <=#Tp 1'b0; |
else |
if(StartTxDataRead & r_DmaEn) |
524,9 → 527,9
assign StartTxStatusWrite = TxEn & ~BlockingTxStatusWrite & (TxDone_wb | TxAbort_wb | TxCtrlEndFrm_wb); |
assign ResetTxStatusWrite = TxStatusWrite; |
|
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxStatusWrite <=#Tp 1'b0; |
else |
if(StartTxStatusWrite) |
538,9 → 541,9
|
|
// Status writing must occur only once. Meanwhile it is blocked. |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
BlockingTxStatusWrite <=#Tp 1'b0; |
else |
if(StartTxStatusWrite) |
553,9 → 556,9
|
// After a tx status write is finished, a new tx buffer descriptor is read. Signal must be |
// latched because new BD read doesn't occur immediately. |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxStatusWriteOccured <=#Tp 1'b0; |
else |
if(StartTxStatusWrite) |
567,9 → 570,9
|
|
// TxBDRead state is activated only once. |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
BlockingTxBDRead <=#Tp 1'b0; |
else |
if(StartTxBDRead) |
582,9 → 585,9
|
// Latching status from the tx buffer descriptor |
// Data is avaliable one cycle after the access is started (at that time signal TxEn is not active) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxStatus <=#Tp 32'h0; |
else |
if(TxBDRead & TxEn) |
593,9 → 596,9
|
|
//Latching length from the buffer descriptor; |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxLength <=#Tp 16'h0; |
else |
if(TxBDRead & TxEn) |
613,9 → 616,9
|
// Latching Rx buffer descriptor status |
// Data is avaliable one cycle after the access is started (at that time signal RxEn is not active) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxStatus <=#Tp 16'h0; |
else |
if(RxBDRead & RxEn) |
625,9 → 628,9
|
// Signal GetNewTxData_wb that requests new data from the DMA must be latched since the DMA response |
// might be delayed. |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
GetNewTxData_wb_latched <=#Tp 1'b0; |
else |
if(GetNewTxData_wb) |
639,9 → 642,9
|
|
// New tx data is avaliable after the DMA access is finished |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
NewTxDataAvaliable_wb <=#Tp 1'b0; |
else |
if(DMACycleFinishedTx & GetNewTxData_wb_latched) |
654,9 → 657,9
|
// Tx Buffer descriptor is only read at the beginning. This signal is used for generation of the |
// TxStartFrm_wb signal. |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxBDAccessed <=#Tp 1'b0; |
else |
if(TxBDRead) |
668,9 → 671,9
|
|
// TxStartFrm_wb: indicator of the start frame (synchronized to WB_CLK_I) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxStartFrm_wb <=#Tp 1'b0; |
else |
if(DMACycleFinishedTx & TxBDAccessed & ~TxStartFrm_wb) |
686,9 → 689,9
|
|
// Input latch of the end-of-frame indicator |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxEndFrm_wbLatched <=#Tp 1'b0; |
else |
if(TxEndFrm_wb) |
704,9 → 707,9
|
|
// Latching valid bytes |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxValidBytesLatched <=#Tp 2'h0; |
else |
if(TxEndFrm_wb & ~TxEndFrm_wbLatched) |
718,9 → 721,9
|
|
// Input Tx data latch |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxDataLatched_wb <=#Tp 32'h0; |
else |
if(DMACycleFinishedTx) |
729,9 → 732,9
|
|
// TxStartFrmRequest is set when a new frame is avaliable or when new data of the same frame is avaliable) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxStartFrmRequest <=#Tp 1'b0; |
else |
if(TxStartFrm_wb | NewTxDataAvaliable_wb) |
795,9 → 798,9
|
|
// Latching Tx buffer descriptor address |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxBDAddress <=#Tp 8'h0; |
else |
if(TxStatusWrite) |
806,9 → 809,9
|
|
// Latching Rx buffer descriptor address |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxBDAddress <=#Tp 8'h0; |
else |
if(TX_BD_NUM_Wr) // When r_TxBDNum is updated, RxBDAddress is also |
820,9 → 823,9
|
|
// Selecting Tx or Rx buffer descriptor address |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
BDAddress <=#Tp 8'h0; |
else |
if(TxEn) |
844,9 → 847,9
|
|
// Generating delayed signals |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
begin |
TxRestart_wb_q <=#Tp 1'b0; |
TxDone_wb_q <=#Tp 1'b0; |
872,9 → 875,9
|
|
// Next descriptor for Tx DMA channel |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
WB_ND_O_TX <=#Tp 1'b0; |
else |
if(TxDonePulse | TxAbortPulse) |
891,9 → 894,9
|
|
// Restart descriptor for DMA channel 0 (Tx) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
WB_RD_O <=#Tp 1'b0; |
else |
if(TxRestartPulse) |
905,7 → 908,7
|
|
assign SetClearTxBDReady = ~TxUsedData & TxUsedData_q; |
assign ResetClearTxBDReady = ClearTxBDReady | WB_RST_I; |
assign ResetClearTxBDReady = ClearTxBDReady | Reset; |
|
|
always @ (posedge SetClearTxBDReady or posedge ResetClearTxBDReady) |
916,9 → 919,9
ClearTxBDReadySync1 <=#Tp 1'b1; |
end |
|
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
ClearTxBDReadySync2 <=#Tp 1'b0; |
else |
if(ClearTxBDReadySync1 & ~ClearTxBDReady) |
928,9 → 931,9
end |
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
ClearTxBDReady <=#Tp 1'b0; |
else |
if(ClearTxBDReadySync2 & ~ClearTxBDReady) |
942,14 → 945,14
|
|
// Latching and synchronizing the Tx pause request signal |
eth_sync_clk1_clk2 syn1 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(TxPauseRq), .sync_out(TPauseRqSync2) |
eth_sync_clk1_clk2 syn1 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(Reset), |
.reset2(Reset), .set2(TxPauseRq), .sync_out(TPauseRqSync2) |
); |
|
|
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TPauseRq <=#Tp 1'b0; |
else |
if(TPauseRq ) |
962,9 → 965,9
|
|
// Generating delayed signals |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
begin |
TxAbort_q <=#Tp 1'b0; |
TxDone_q <=#Tp 1'b0; |
985,8 → 988,8
// Sinchronizing and evaluating tx data |
assign SetGotData = (TxStartFrm_wb | NewTxDataAvaliable_wb & ~TxAbort_wb & ~TxRetry_wb) & ~WB_CLK_I; |
|
eth_sync_clk1_clk2 syn2 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(SetGotData), .sync_out(GotDataSync3)); |
eth_sync_clk1_clk2 syn2 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(Reset), |
.reset2(Reset), .set2(SetGotData), .sync_out(GotDataSync3)); |
|
|
// Evaluating data. If abort or retry occured meanwhile than data is ignored. |
994,9 → 997,9
|
|
// Indication of good data |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
GotData <=#Tp 1'b0; |
else |
if(GotDataEvaluate) |
1007,9 → 1010,9
|
|
// Tx start frame generation |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxStartFrm <=#Tp 1'b0; |
else |
if(TxUsedData_q | TxAbort & ~TxAbort_q | TxRetry & ~TxRetry_q) |
1021,9 → 1024,9
|
|
// Indication of the last word |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
LastWord <=#Tp 1'b0; |
else |
if((TxEndFrm | TxAbort | TxRetry) & Flop) |
1035,9 → 1038,9
|
|
// Tx end frame generation |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxEndFrm <=#Tp 1'b0; |
else |
if(Flop & TxEndFrm | TxAbort | TxRetry_q) |
1057,9 → 1060,9
|
|
// Tx data selection (latching) |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxData <=#Tp 8'h0; |
else |
if(GotData & ~TxStartFrm & ~TxUsedData) |
1078,9 → 1081,9
|
|
// Latching tx data |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxDataLatched[31:0] <=#Tp 32'h0; |
else |
if(GotData & ~TxUsedData & ~TxStartFrm) |
1092,7 → 1095,7
|
|
// Generation of the DataNotAvaliable signal which is used for the generation of the TxUnderRun signal |
assign ResetDataNotAvaliable = DMACycleFinishedTx_q | WB_RST_I; |
assign ResetDataNotAvaliable = DMACycleFinishedTx_q | Reset; |
assign SetDataNotAvaliable = GotData & ~TxUsedData & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3; |
|
always @ (posedge MTxClk or posedge ResetDataNotAvaliable) |
1106,9 → 1109,9
|
|
// Tx under run |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxUnderRun <=#Tp 1'b0; |
else |
if(TxAbort & ~TxAbort_q) |
1121,9 → 1124,9
|
|
// Tx Byte counter |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxByteCnt <=#Tp 2'h0; |
else |
if(TxAbort_q | TxRetry_q) |
1138,9 → 1141,9
|
|
// Generation of the GetNewTxData signal |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
GetNewTxData <=#Tp 1'b0; |
else |
if(GetNewTxData) |
1155,9 → 1158,9
|
|
// TxRetryLatched |
always @ (posedge MTxClk or posedge WB_RST_I) |
always @ (posedge MTxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxRetryLatched <=#Tp 1'b0; |
else |
if(TxStartFrm) |
1168,14 → 1171,8
end |
|
|
|
// Synchronizing request for a new tx data |
|
//ne eth_sync_clk1_clk2 syn3 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I), |
// .set2(SetGotData), .sync_out(GotDataSync3)); |
|
// This section still needs to be changed due to ASIC demands |
assign ResetSyncGetNewTxData_wb = SyncGetNewTxData_wb3 | TxAbort_wb | TxRetry_wb | WB_RST_I; |
assign ResetSyncGetNewTxData_wb = SyncGetNewTxData_wb3 | TxAbort_wb | TxRetry_wb | Reset; |
assign SetSyncGetNewTxData_wb = GetNewTxData; |
|
|
1190,9 → 1187,9
|
|
// Sync. stage 2 |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
SyncGetNewTxData_wb2 <=#Tp 1'b0; |
else |
if(SyncGetNewTxData_wb1 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb) |
1203,9 → 1200,9
|
|
// Sync. stage 3 |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
SyncGetNewTxData_wb3 <=#Tp 1'b0; |
else |
if(SyncGetNewTxData_wb2 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb) |
1216,9 → 1213,9
|
|
// Synchronized request for a new tx data |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
GetNewTxData_wb <=#Tp 1'b0; |
else |
if(GetNewTxData_wb) |
1231,15 → 1228,15
|
// Synchronizine transmit done signal |
// Sinchronizing and evaluating tx data |
eth_sync_clk1_clk2 syn4 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(TxDone), .sync_out(TxDoneSync3) |
eth_sync_clk1_clk2 syn4 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(Reset), |
.reset2(Reset), .set2(TxDone), .sync_out(TxDoneSync3) |
); |
|
|
// Syncronized signal TxDone_wb (sync. to WISHBONE clock) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxDone_wb <=#Tp 1'b0; |
else |
if(TxStartFrm_wb | WillSendControlFrame) |
1250,7 → 1247,7
end |
|
|
assign ResetTxCtrlEndFrm_wb = TxCtrlEndFrm_wb | WB_RST_I; |
assign ResetTxCtrlEndFrm_wb = TxCtrlEndFrm_wb | Reset; |
assign SetTxCtrlEndFrm_wb = TxCtrlEndFrm; |
|
|
1265,9 → 1262,9
|
|
// Sync stage 2 |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxCtrlEndFrm_wbSync2 <=#Tp 1'b0; |
else |
if(TxCtrlEndFrm_wbSync1 & ~TxCtrlEndFrm_wb) |
1278,9 → 1275,9
|
|
// Synchronized Tx control end frame |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxCtrlEndFrm_wb <=#Tp 1'b0; |
else |
if(TxCtrlEndFrm_wbSync2 & ~TxCtrlEndFrm_wb) |
1292,14 → 1289,14
|
|
// Synchronizing TxRetry signal |
eth_sync_clk1_clk2 syn6 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(TxRetryLatched), .sync_out(TxRetrySync3)); |
eth_sync_clk1_clk2 syn6 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(Reset), |
.reset2(Reset), .set2(TxRetryLatched), .sync_out(TxRetrySync3)); |
|
|
// Synchronized signal TxRetry_wb (synchronized to WISHBONE clock) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxRetry_wb <=#Tp 1'b0; |
else |
if(TxStartFrm_wb | WillSendControlFrame) |
1311,14 → 1308,14
|
|
// Synchronizing TxAbort signal |
eth_sync_clk1_clk2 syn7 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(TxAbort), .sync_out(TxAbortSync3)); |
eth_sync_clk1_clk2 syn7 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(Reset), |
.reset2(Reset), .set2(TxAbort), .sync_out(TxAbortSync3)); |
|
|
// Synchronized TxAbort_wb signal (synchronized to WISHBONE clock) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
TxAbort_wb <=#Tp 1'b0; |
else |
if(TxStartFrm_wb) |
1336,9 → 1333,9
|
|
// Latching READY status of the Rx buffer descriptor |
always @ (negedge WB_CLK_I or posedge WB_RST_I) |
always @ (negedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxBDReady <=#Tp 1'b0; |
else |
if(RxEn & RxBDRead) |
1350,9 → 1347,9
|
|
// Reading the Rx buffer descriptor |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxBDRead <=#Tp 1'b1; |
else |
if(StartRxBDRead) |
1369,9 → 1366,9
|
|
// Writing status back to the Rx buffer descriptor |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxStatusWrite <=#Tp 1'b0; |
else |
if(StartRxStatusWrite) |
1386,9 → 1383,9
|
|
// Latched status that a status write occured. |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxStatusWriteOccured <=#Tp 1'b0; |
else |
if(StartRxStatusWrite) |
1401,15 → 1398,15
|
|
// Generation of the synchronized signal ShiftEnded that indicates end of reception |
eth_sync_clk1_clk2 syn8 (.clk1(MRxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(RxEndFrm_wb), .sync_out(ShiftEnded) |
eth_sync_clk1_clk2 syn8 (.clk1(MRxClk), .clk2(WB_CLK_I), .reset1(Reset), |
.reset2(Reset), .set2(RxEndFrm_wb), .sync_out(ShiftEnded) |
); |
|
|
// Indicating that last byte is being reveived |
always @ (posedge MRxClk or posedge WB_RST_I) |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
LastByteIn <=#Tp 1'b0; |
else |
if(ShiftWillEnd & (&RxByteCnt)) |
1421,9 → 1418,9
|
|
// Indicating that data reception will end |
always @ (posedge MRxClk or posedge WB_RST_I) |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
ShiftWillEnd <=#Tp 1'b0; |
else |
if(ShiftEnded) |
1435,9 → 1432,9
|
|
// Receive byte counter |
always @ (posedge MRxClk or posedge WB_RST_I) |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxByteCnt <=#Tp 2'h0; |
else |
if(ShiftEnded) |
1449,9 → 1446,9
|
|
// Indicates how many bytes are valid within the last word |
always @ (posedge MRxClk or posedge WB_RST_I) |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxValidBytes <=#Tp 2'h1; |
else |
if(ShiftEnded) |
1464,9 → 1461,9
|
// There is a maximum 3 MRxClk delay between RxDataLatched2 and RxData_wb. In the meantime data |
// is stored to the RxDataLatched1. |
always @ (posedge MRxClk or posedge WB_RST_I) |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxDataLatched1 <=#Tp 16'h0; |
else |
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h0) |
1478,9 → 1475,9
|
|
// Latching incoming data to buffer |
always @ (posedge MRxClk or posedge WB_RST_I) |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxDataLatched2 <=#Tp 32'h0; |
else |
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h2) |
1492,9 → 1489,9
|
|
// Indicating start of the reception process |
always @ (posedge MRxClk or posedge WB_RST_I) |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
StartShifting <=#Tp 1'b0; |
else |
if((RxValid & RxBDReady & ~RxStartFrm & (&RxByteCnt)) | (ShiftWillEnd & LastByteIn & (&RxByteCnt))) |
1507,15 → 1504,15
// Synchronizing Rx start frame to the WISHBONE clock |
assign StartRxStartFrmSync1 = RxStartFrm & RxBDReady; |
|
eth_sync_clk1_clk2 syn9 (.clk1(WB_CLK_I), .clk2(MRxClk), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(SetGotData), .sync_out(RxStartFrmSync3) |
eth_sync_clk1_clk2 syn9 (.clk1(WB_CLK_I), .clk2(MRxClk), .reset1(Reset), |
.reset2(Reset), .set2(SetGotData), .sync_out(RxStartFrmSync3) |
); |
|
|
// Generating synchronized Rx start frame |
always @ ( posedge WB_CLK_I or posedge WB_RST_I) |
always @ ( posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxStartFrm_wb <=#Tp 1'b0; |
else |
if(RxStartFrmSync3 & ~RxStartFrm_wb) |
1525,13 → 1522,8
end |
|
|
//Synchronizing signal for latching data that will be written to the WISHBONE |
//eth_sync_clk1_clk2 syn10 (.clk1(WB_CLK_I), .clk2(MRxClk), .reset1(WB_RST_I), .reset2(WB_RST_I), |
// .set2(StartShifting), .sync_out(LatchNow_wb) |
// ); |
|
// This section still needs to be changed due to ASIC demands |
assign ResetShifting_wb = LatchNow_wb | WB_RST_I; |
assign ResetShifting_wb = LatchNow_wb | Reset; |
assign StartShifting_wb = StartShifting; |
|
|
1546,9 → 1538,9
|
|
// Sync. stage 2 |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
Shifting_wb_Sync2 <=#Tp 1'b0; |
else |
if(Shifting_wb_Sync1 & ~RxDataValid_wb) |
1559,9 → 1551,9
|
|
// Generating synchronized signal that will latch data for writing to the WISHBONE |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
LatchNow_wb <=#Tp 1'b0; |
else |
if(Shifting_wb_Sync2 & ~RxDataValid_wb) |
1572,9 → 1564,9
|
|
// Indicating that valid data is avaliable |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxDataValid_wb <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb) |
1586,9 → 1578,9
|
|
// Forcing next descriptor in the DMA (Channel 1 is used for rx) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
WB_REQ_O_RX <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb & r_DmaEn) |
1604,9 → 1596,9
|
|
// WbWriteError is generated when the previous word is not written to the wishbone on time |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
WbWriteError <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb) |
1621,9 → 1613,9
|
|
// Assembling data that will be written to the WISHBONE |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxData_wb <=#Tp 32'h0; |
else |
if(LatchNow_wb & ~RxDataValid_wb & ~ShiftWillEnd) |
1644,9 → 1636,9
|
|
// Generation of the end-of-frame signal |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(WB_RST_I) |
if(Reset) |
RxEndFrm_wb <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb & ShiftWillEnd) |
/trunk/rtl/verilog/eth_top.v
41,6 → 41,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.9 2002/01/23 10:28:16 mohor |
// Link in the header changed. |
// |
// Revision 1.8 2001/12/05 15:00:16 mohor |
// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors |
// instead of the number of RX descriptors). |
100,13 → 103,23
|
// WISHBONE slave |
wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o, |
wb_req_o, wb_ack_i, wb_nd_o, wb_rd_o, |
wb_ack_i, |
|
`ifdef WISHBONE_DMA |
wb_req_o, wb_nd_o, wb_rd_o, |
`else |
// WISHBONE master |
m_wb_adr_o, m_wb_sel_o, m_wb_we_o, |
m_wb_dat_o, m_wb_dat_i, m_wb_cyc_o, |
m_wb_stb_o, m_wb_ack_i, m_wb_err_i, |
`endif |
|
//TX |
mtx_clk_pad_i, mtxd_pad_o, mtxen_pad_o, mtxerr_pad_o, |
|
//RX |
mrx_clk_pad_i, mrxd_pad_i, mrxdv_pad_i, mrxerr_pad_i, mcoll_pad_i, mcrs_pad_i, |
RxAbort, |
|
// MIIM |
mdc_pad_o, md_pad_i, md_pad_o, md_padoen_o, |
135,12 → 148,26
input wb_stb_i; // WISHBONE strobe input |
output wb_ack_o; // WISHBONE acknowledge output |
|
`ifdef WISHBONE_DMA |
// DMA |
input [1:0] wb_ack_i; // DMA acknowledge input |
output [1:0] wb_req_o; // DMA request output |
output [1:0] wb_nd_o; // DMA force new descriptor output |
output wb_rd_o; // DMA restart descriptor output |
`else |
// WISHBONE master |
output [31:0] m_wb_adr_o; |
output [3:0] m_wb_sel_o; |
output m_wb_we_o; |
input [31:0] m_wb_dat_i; |
output [31:0] m_wb_dat_o; |
output m_wb_cyc_o; |
output m_wb_stb_o; |
input m_wb_ack_i; |
input m_wb_err_i; |
`endif |
|
input [1:0] wb_ack_i; // DMA acknowledge input |
|
// Tx |
input mtx_clk_pad_i; // Transmit clock (from PHY) |
output [3:0] mtxd_pad_o; // Transmit nibble (to PHY) |
156,6 → 183,8
// Common Tx and Rx |
input mcoll_pad_i; // Collision (from PHY) |
input mcrs_pad_i; // Carrier sense (from PHY) |
input RxAbort; // igor !!! Ta se mora preseliti da bo prisel iz enega izmed modulov. Tu je le zaradi |
// testiranja. Pove, kdaj adresa ni ustrezala in se paketi sklirajo, stevci pa resetirajo. |
|
// MII Management interface |
input md_pad_i; // MII data input (from I/O cell) |
299,6 → 328,7
wire RxValid; |
wire RxStartFrm; |
wire RxEndFrm; |
wire RxAbort; |
|
wire WillTransmit; // Will transmit (to RxEthMAC) |
wire ResetCollision; // Reset Collision (for synchronizing collision) |
313,7 → 343,7
// Connecting MACControl |
eth_maccontrol maccontrol1 |
( |
.MTxClk(mtx_clk_pad_i), .TPauseRq(TPauseRq), |
.MTxClk(mtx_clk_pad_i), .TPauseRq(TPauseRq), |
.TxPauseTV(TxPauseTV), .TxDataIn(TxData), |
.TxStartFrmIn(TxStartFrm), .TxEndFrmIn(TxEndFrm), |
.TxUsedDataIn(TxUsedDataIn), .TxDoneIn(TxDoneIn), |
495,17 → 525,33
|
|
// Connecting WishboneDMA module |
eth_wishbonedma wbdma |
`ifdef WISHBONE_DMA |
eth_wishbonedma wishbone |
`else |
eth_wishbone wishbone |
`endif |
( |
.WB_CLK_I(wb_clk_i), .WB_RST_I(wb_rst_i), .WB_DAT_I(wb_dat_i), |
.WB_CLK_I(wb_clk_i), .WB_DAT_I(wb_dat_i), |
.WB_DAT_O(DMA_WB_DAT_O), |
|
// WISHBONE slave |
.WB_ADR_I(wb_adr_i[9:2]), .WB_SEL_I(wb_sel_i), .WB_WE_I(wb_we_i), |
.BDCs(BDCs), .WB_ACK_O(BDAck), |
.WB_REQ_O(wb_req_o), .WB_ACK_I(wb_ack_i), .WB_ND_O(wb_nd_o), |
.WB_RD_O(wb_rd_o), |
|
.Reset(wb_rst_i), |
|
`ifdef WISHBONE_DMA |
.WB_REQ_O(wb_req_o), .WB_ND_O(wb_nd_o), .WB_RD_O(wb_rd_o), |
.WB_ACK_I(wb_ack_i), |
`else |
// WISHBONE master |
.m_wb_adr_o(m_wb_adr_o), .m_wb_sel_o(m_wb_sel_o), .m_wb_we_o(m_wb_we_o), |
.m_wb_dat_i(m_wb_dat_i), .m_wb_dat_o(m_wb_dat_o), .m_wb_cyc_o(m_wb_cyc_o), |
.m_wb_stb_o(m_wb_stb_o), .m_wb_ack_i(m_wb_ack_i), .m_wb_err_i(m_wb_err_i), |
`endif |
|
|
|
//TX |
.MTxClk(mtx_clk_pad_i), .TxStartFrm(TxStartFrm), .TxEndFrm(TxEndFrm), |
.TxUsedData(TxUsedData), .TxData(TxData), .StatusIzTxEthMACModula(16'h0), |
520,10 → 566,16
|
//RX |
.MRxClk(mrx_clk_pad_i), .RxData(RxData), .RxValid(RxValid), |
.RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), |
.RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), |
.Busy_IRQ(Busy_IRQ), .RxF_IRQ(RxF_IRQ), .RxB_IRQ(RxB_IRQ), |
.TxE_IRQ(TxE_IRQ), .TxB_IRQ(TxB_IRQ) |
|
`ifdef WISHBONE_DMA |
`else |
, |
.RxAbort(RxAbort) |
`endif |
|
); |
|
|
531,7 → 583,7
// Connecting MacStatus module |
eth_macstatus macstatus1 |
( |
.MRxClk(mrx_clk_pad_i), .Reset(r_Rst), .TransmitEnd(), |
.MRxClk(mrx_clk_pad_i), .Reset(r_Rst), .TransmitEnd(), |
.ReceiveEnd(ReceiveEnd), .ReceivedPacketGood(ReceivedPacketGood), .ReceivedLengthOK(ReceivedLengthOK), |
.RxCrcError(RxCrcError), .MRxErr(MRxErr_Lb), .MRxDV(MRxDV_Lb), |
.RxStateSFD(RxStateSFD), .RxStateData(RxStateData), .RxStatePreamble(RxStatePreamble), |