URL
https://opencores.org/ocsvn/openarty/openarty/trunk
Subversion Repositories openarty
Compare Revisions
- This comparison shows the changes necessary to convert path
/openarty/trunk/rtl
- from Rev 30 to Rev 31
- ↔ Reverse comparison
Rev 30 → Rev 31
/rxecrc.v
0,0 → 1,157
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: rxecrc.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To detect any CRC errors in the packet as received. The CRC |
// is not stripped as part of this process. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
`define CRCBIT8 32'hedb88320 |
`define CRCBIT4 32'h76dc4190 |
`define CRCBIT2 32'h3b6e20c8 |
`define CRCBIT1 32'h1db71064 |
module rxecrc(i_clk, i_ce, i_en, i_cancel, i_v, i_d, o_v, o_d, o_err); |
input i_clk, i_ce, i_en, i_cancel; |
input i_v; |
input [3:0] i_d; |
output reg o_v; |
output reg [3:0] o_d; |
output wire o_err; |
|
reg r_err; |
reg [6:0] r_mq; // Partial CRC matches |
reg [3:0] r_mp; // Prior CRC matches |
|
reg [31:0] r_crc; |
reg [27:0] r_crc_q0; |
reg [23:0] r_crc_q1; |
reg [19:0] r_crc_q2; |
reg [15:0] r_crc_q3; |
reg [11:0] r_crc_q4; |
reg [ 7:0] r_crc_q5; |
reg [ 3:0] r_crc_q6; |
|
reg [14:0] r_buf; |
|
wire [3:0] lownibble; |
assign lownibble = r_crc[3:0] ^ i_d; |
|
wire [31:0] shifted_crc; |
assign shifted_crc = { 4'h0, r_crc[27:0] }; |
always @(posedge i_clk) |
if (i_ce) |
begin |
|
r_crc_q0 <= r_crc[31:4]; |
r_crc_q1 <= r_crc_q0[27:4]; |
r_crc_q2 <= r_crc_q1[23:4]; |
r_crc_q3 <= r_crc_q2[19:4]; |
r_crc_q4 <= r_crc_q3[15:4]; |
r_crc_q5 <= r_crc_q4[11:4]; |
r_crc_q6 <= r_crc_q5[ 7:4]; |
|
r_buf <= { r_buf[9:0], i_v, i_d }; |
if (((!i_ce)&&(!o_v))||(i_cancel)) |
begin |
r_crc <= 32'hffff_ffff; |
r_err <= 1'b0; |
|
r_mq[6:0] <= 7'h0; |
|
r_mp <= 4'h0; |
|
r_buf[ 4] <= 1'b0; |
r_buf[ 9] <= 1'b0; |
r_buf[14] <= 1'b0; |
end else |
begin |
/// Calculate the CRC |
case(lownibble) |
4'h0: r_crc <= shifted_crc; |
4'h1: r_crc <= shifted_crc ^ `CRCBIT1; |
4'h2: r_crc <= shifted_crc ^ `CRCBIT2; |
4'h3: r_crc <= shifted_crc ^ `CRCBIT2 ^ `CRCBIT1; |
4'h4: r_crc <= shifted_crc ^ `CRCBIT4; |
4'h5: r_crc <= shifted_crc ^ `CRCBIT4 ^ `CRCBIT1; |
4'h6: r_crc <= shifted_crc ^ `CRCBIT4 ^ `CRCBIT2; |
4'h7: r_crc <= shifted_crc ^ `CRCBIT4 ^ `CRCBIT2 ^ `CRCBIT1; |
4'h8: r_crc <= shifted_crc ^ `CRCBIT8; |
4'h9: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT1; |
4'ha: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT2; |
4'hb: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT2 ^ `CRCBIT1; |
4'hc: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4; |
4'hd: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4 ^ `CRCBIT1; |
4'he: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4 ^ `CRCBIT2; |
4'hf: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4 ^ `CRCBIT2 ^ `CRCBIT1; |
endcase |
|
r_mq[0] <= (i_v)&&(i_d == r_crc[3:0]); |
r_mq[1] <= (r_mq[0])&&(i_v)&&(i_d == r_crc_q0[3:0]); |
r_mq[2] <= (r_mq[1])&&(i_v)&&(i_d == r_crc_q1[3:0]); |
r_mq[3] <= (r_mq[2])&&(i_v)&&(i_d == r_crc_q2[3:0]); |
r_mq[4] <= (r_mq[3])&&(i_v)&&(i_d == r_crc_q3[3:0]); |
r_mq[5] <= (r_mq[4])&&(i_v)&&(i_d == r_crc_q4[3:0]); |
r_mq[6] <= (r_mq[5])&&(i_v)&&(i_d == r_crc_q5[3:0]); |
//r_mq7<=(r_mq6)&&(i_v)&&(i_d == r_crc_q6[3:0]); |
|
r_mp <= { r_mp[2:0], |
(r_mq[6])&&(i_v)&&(i_d == r_crc_q6[3:0]) }; |
|
// Now, we have an error if ... |
// On the first empty, none of the prior N matches |
// matched. |
r_err <= (r_err)||((i_en)&&(!i_v)&&(r_buf[4])&&(r_mp == 4'h0)); |
if ((!i_v)&&(r_buf[4])) |
begin |
if (r_mp[3]) |
begin |
r_buf[ 4] <= 1'b0; |
r_buf[ 9] <= 1'b0; |
r_buf[14] <= 1'b0; |
end else if (r_mp[2]) |
begin |
r_buf[4] <= 1'b0; |
r_buf[9] <= 1'b0; |
end else if (r_mp[1]) |
r_buf[4] <= 1'b0; |
// else if (r_mp[0]) ... keep everything |
end |
|
o_v <= r_buf[14]; |
o_d <= r_buf[13:10]; |
end |
end |
|
assign o_err = r_err; |
|
endmodule |
/rxehwmac.v
0,0 → 1,116
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: rxehwmac.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To remove MACs that aren't our own. The input is a nibble |
// stream, where the first nibble is the first nibble of the |
// destination MAC (our MAC). If enabled, this MAC is removed from the |
// stream. If the MAC matches, the stream is allowed to continue. If |
// the MAC doesn't match, the packet is thrown away. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module rxehwmac(i_clk, i_ce, i_en, i_cancel, i_hwmac, i_v, i_d, o_v, o_d, o_err, o_broadcast); |
input i_clk, i_ce, i_en, i_cancel; |
input [47:0] i_hwmac; |
input i_v; |
input [3:0] i_d; |
output reg o_v; |
output reg [3:0] o_d; |
output wire o_err; |
output reg o_broadcast; |
|
reg [47:0] r_hwmac; |
reg r_cancel, r_err, r_hwmatch, r_broadcast; |
reg [19:0] r_buf; |
reg [29:0] r_p; |
|
always @(posedge i_clk) |
if (i_ce) |
begin |
if (i_cancel) |
r_cancel <= 1'b1; |
else if ((!i_v)&&(!o_v)) |
r_cancel <= 1'b0; |
|
if ((i_en)&&(i_v)&&(r_p[11])) |
begin |
if (r_hwmac[47:44] != i_d) |
r_hwmatch <= 1'b0; |
if (4'hf != i_d) |
r_broadcast<= 1'b0; |
end |
|
r_err <= (i_en)&&(!r_hwmatch)&&(!r_broadcast)&&(i_v); |
o_broadcast <= (r_broadcast)&&(!r_p[11])&&(i_v); |
|
r_buf <= { r_buf[14:0], i_v, i_d }; |
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
r_p <= 30'h3fff_ffff; |
r_hwmac <= i_hwmac; |
r_hwmatch <= 1'b1; |
r_broadcast <= 1'b1; |
r_buf[ 4] <= 1'b0; |
r_buf[ 9] <= 1'b0; |
r_buf[14] <= 1'b0; |
r_buf[19] <= 1'b0; |
o_v <= 1'b0; |
o_d <= i_d; |
end else begin |
r_p <= { r_p[28:0], 1'b0 }; |
if (i_en) |
begin |
// Skip the first 6 bytes, and everything |
// following if the MAC doesn't match |
o_v <= (!r_p[11])&&(!r_cancel)&&(i_v); |
o_d <= i_d; |
end else begin |
// In this case, we wish to ignore everything, |
// but still duplicate the EtherType words |
if (r_p[27]) |
{ o_v, o_d } <= { (i_v)&&(!r_cancel), i_d }; |
else |
{ o_v, o_d } <= { (r_buf[19])&&(!r_cancel), r_buf[18:15] }; |
end |
end |
|
if ((!i_en)&&(r_p[27])) |
begin // Clear out the top half of the EtherType word |
r_buf[18:15] <= 4'h0; |
r_buf[13:10] <= 4'h0; |
end |
end |
|
assign o_err = r_err; |
|
endmodule |
/rxepreambl.v
0,0 → 1,70
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: rxepreambl.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To detect, and then remove, any ethernet hardware preamble. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module rxepreambl(i_clk, i_ce, i_en, i_cancel, i_v, i_d, o_v, o_d); |
input i_clk, i_ce, i_en, i_cancel; |
input i_v; |
input [3:0] i_d; |
output reg o_v; |
output reg [3:0] o_d; |
|
reg r_inpkt, r_cancel; |
reg [14:0] r_buf; |
|
always @(posedge i_clk) |
if(i_ce) |
begin |
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
// Set us up |
r_inpkt <= 1'b0; |
r_cancel <= (i_v)||(o_v); |
end else if (r_cancel) |
r_cancel <= (i_v)||(o_v); |
|
if ((i_en)&&(!r_inpkt)) |
begin |
r_buf <= { r_buf[9:0], i_v, i_d }; |
r_inpkt <= (!r_cancel)&&((r_buf == { 5'h15, 5'h15, 5'h15 })&&(i_v)&&(i_d == 4'hd)); |
o_v <= 1'b0; |
end else begin |
o_v <= (i_v)&&(!r_cancel)&&(r_inpkt); |
o_d <= i_d; |
end |
end |
endmodule |
|
/rxewrite.v
0,0 → 1,94
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: rxewrite.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: The purpose of this module is quite simple: to simplify the |
// receive process. By running the receive data through a |
// series of "filter" processes (of which this is one), I hope to reduce |
// the complexity of the filter design. This particular filter determines |
// if/when to write to memory, and at what address to write to. Further, |
// because nibbles come into the interface in LSB order, and because we |
// are storing the first byte in the MSB, we need to shuffle bytes around |
// in this interface. Therefore, this interface is also design to make |
// certain that, no matter how many bytes come in, we have always |
// written a complete word to the output. Hence, each word may be |
// written 8-times (once for each nibble) ... but that be as it may. |
// |
// This routine also measures packet length in bytes. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module rxewrite(i_clk, i_ce, i_cancel, i_v, i_d, o_v, o_addr, o_data, o_len); |
parameter AW = 12; |
localparam DW = 32; |
input i_clk, i_ce; |
input i_cancel; |
input i_v; |
input [3:0] i_d; |
output reg o_v; |
output reg [(AW-1):0] o_addr; |
output reg [(DW-1):0] o_data; |
output wire [(AW+1):0] o_len; |
|
reg [(AW+2):0] lcl_addr, r_len; |
|
initial r_len = 0; |
always @(posedge i_clk) |
if (i_ce) |
begin |
lcl_addr <= lcl_addr + 1'b1; |
if (i_v) |
r_len <= lcl_addr + {{(AW+1){1'b0}},2'b10}; // i.e. +2 |
o_v <= i_v; |
case(lcl_addr[2:0]) |
3'b000: o_data <= { 4'h0, i_d, 24'h00 }; |
3'b001: o_data <= { i_d, o_data[27:24], 24'h00 }; |
3'b010: o_data <= { o_data[31:24], 4'h0, i_d, 16'h00 }; |
3'b011: o_data <= { o_data[31:24], i_d, o_data[19:16], 16'h00 }; |
3'b100: o_data <= { o_data[31:16], 4'h0, i_d, 8'h00 }; |
3'b101: o_data <= { o_data[31:16], i_d, o_data[11:8], 8'h00 }; |
3'b110: o_data <= { o_data[31: 8], 4'h0, i_d }; |
3'b111: o_data <= { o_data[31: 8], i_d, o_data[3:0] }; |
endcase |
o_addr <= lcl_addr[(AW+2):3]; |
|
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
o_v <= 0; |
lcl_addr <= 0; |
end |
end |
|
assign o_len = r_len[(AW+2):1]; |
|
endmodule |
|