我的
FPGA板子是Siga-S16,Xilinx Spartan-6,网卡是RTL8201CP。
这个板子其实不需要做任何设定,因为
开发板本身已经设置好了相关寄存器的配置管脚。默认就是100M全双工
通信。也板载了25M的晶振,直接通过E_TXC管脚可以取到25MHz的信号。上电之后只要拉高10ms之后再拉低网卡的E_RESET就好了。用示波器可以测出E_TXC的20MHz信号。
然后每隔1秒钟进入准备发送数据状态,然后按照状态机的顺序一直走。
我打开E_TXEN并且敏感电平检测E_TXC信号的下降沿,在每个下降沿从高位到地位开始往E_TXD上发送数据。从MAC前导码,到MAC,IP,UDP,最后CRC,最后停止发送将状态切换回idle空闲状态。
大家可以看看我的代码有啥问题吗?求指点,非常感谢。已经debug了好几天了一直没找到原因。
module first(
input clk,
input rst_n,
input E_RXC,
// output E_RXER,
//output[3:0] E_RXD,
input E_TXC,
output E_RESET,
output wire E_TXEN,
output reg[3:0] E_TXD,
input wire[3:0] key,
output reg[3:0] led,
output gpio1,
output gpio2,
output gpio3
);
// udp
parameter UDP_SRC_PORT = 16'd8080; // LE
parameter UDP_DST_PORT = 16'd8080;
parameter _UDP_DATA_LENGTH_UNIT = 16'd14;
parameter UDP_HEADER_AND_DATA_LENGTH = 16'd8 + _UDP_DATA_LENGTH_UNIT;
parameter UDP_CRC = 16'd0;
// 64bits = 8bytes
parameter UDP_DATA = 112'b1;
// 112bits = 14bytes
// 176bits = 22bytes
// ip
parameter IP_VERSION = 4'd4; // IPV4
parameter IP_HEADER_LENGTH = 4'd5; // header's lenght(1/4bytes)
parameter IP_SERVER_TYPE = 8'h0; //
parameter IP_HEADER_AND_DATA_LENGTH = 16'd0 + UDP_HEADER_AND_DATA_LENGTH + IP_HEADER_LENGTH * 4; // udp length + ip header's lenght
parameter IP_ID = 16'h0; // ID
parameter IP_GROUP_FLAG = 3'b010; // is GROUP? this is no
parameter IP_GROUP_B_SHIFT = 13'd0; // dont group
parameter IP_TTL = 8'h80; // TTL
parameter IP_TRANSPORT_LAYER_PROTOCOL = 8'h11; // UDP
parameter IP_CRC = 16'h0; // CRC
parameter IP_SRC_ADDRESS = {8'd192, 8'd168, 8'd106, 8'd2};
parameter IP_DST_ADDRESS = {8'd192, 8'd168, 8'd106, 8'd1};
parameter IP_OP
tiOPN = 0;
// 160bits = 20bytes
// mac
parameter MAC_PRE = 64'hd5_55_55_55_55_55_55_55; // pre code, required
//parameter _MAC_DST = 48'h00_0e_c6_dc_b4_a4;
parameter _MAC_DST = 48'hff_ff_ff_ff_ff_ff; // boardcast
parameter MAC_DST_ORDERED = ((_MAC_DST<<4 & 48'hf0_f0_f0_f0_f0_f0)|(_MAC_DST>>4 & 48'h0f_0f_0f_0f_0f_0f));
parameter _MAC_SRC = 48'h11_11_11_11_11_11;
parameter MAC_SRC_ORDERED = ((_MAC_SRC<<4 & 48'hf0_f0_f0_f0_f0_f0)|(_MAC_SRC>>4 & 48'h0f_0f_0f_0f_0f_0f));
parameter MAC_TYPE = 16'h0800; // mac frame type: ip
// 176bits = 22bytes
// status
parameter STATUS_IDLE = 4'd0;
parameter STATUS_READY = 4'd1;
parameter STATUS_SEND_PRE = 4'd2;
parameter STATUS_SEND_MAC = 4'd3;// en crc
parameter STATUS_SEND_IP = 4'd4;
parameter STATUS_SEND_UDP = 4'd5;
parameter STATUS_SEND_CRC = 4'd6;
//parameter STATUS_SEND_IP = 4'd4;
//parameter STATUS_SEND_UDP = 4'd5;
//assign led=key;
assign gpio1 = E_TXC;
assign gpio2 = E_RXC;
assign gpio3 = 1;
assign E_RESET = ~key[0];
assign E_TXEN = 0;
wire[7:0] data_in;
reg crc_rst, crc_en;
wire[31:0] crc_next;
wire[31:0] crc_out;
crc(E_TXC, crc_rst, data_in, crc_en, crc_out, crc_next);
assign data_in = {4'b0, E_TXD};
reg[3:0] status;
reg[7:0] i, j;
reg[7:0] crc_reg;
reg[15:0] pre[3:0];
reg[15:0] mac[6:0];
reg[15:0] ip[9:0];
reg[15:0] udp[3:0];
reg[31:0] time_counter;
always @(negedge E_TXC or negedge rst_n)
begin
if (!rst_n) begin
status <= STATUS_IDLE;
time_counter<=0;
led <= 4'b1111;
end
else begin
case (status)
STATUS_IDLE : begin
led <= 4'b1110;
//E_TXEN <= 1;
crc_en <= 0;
crc_rst <= 1;
//E_TXC <= 1'bz;
i <= 0;
if (time_counter==32'd50_000_000) begin //,
status <= STATUS_READY;
time_counter <= 32'd0;
end
else begin
time_counter <= time_counter + 32'd1;
end
end
STATUS_READY : begin
led <= 4'b1100;
pre[0] <= MAC_PRE[63:48];
pre[1] <= MAC_PRE[47:32];
pre[2] <= MAC_PRE[31:16];
pre[3] <= MAC_PRE[15:0];
mac[0] <= MAC_DST_ORDERED[47:32];
mac[1] <= MAC_DST_ORDERED[31:16];
mac[2] <= MAC_DST_ORDERED[15:0];
mac[3] <= MAC_SRC_ORDERED[47:32];
mac[4] <= MAC_SRC_ORDERED[31:16];
mac[5] <= MAC_SRC_ORDERED[15:0];
mac[6] <= MAC_TYPE;
ip[0] <= {IP_VERSION, IP_HEADER_LENGTH, IP_SERVER_TYPE};
ip[1] <= {IP_HEADER_AND_DATA_LENGTH};
ip[2] <= {IP_ID};
ip[3] <= {IP_GROUP_FLAG, IP_GROUP_B_SHIFT};
ip[4] <= {IP_TTL, IP_TRANSPORT_LAYER_PROTOCOL};
ip[5] <= {IP_CRC};
ip[6] <= IP_SRC_ADDRESS[31:16];
ip[7] <= IP_SRC_ADDRESS[15:0];
ip[8] <= IP_DST_ADDRESS[31:16];
ip[9] <= IP_DST_ADDRESS[15:0];
//ip[6] <= {8'd192, 8'd168};
//ip[7] <= {8'd106, 8'd2};
//ip[8] <= {8'd192, 8'd168};
//ip[9] <= {8'd106, 8'd1};
udp[0] <= UDP_SRC_PORT;
udp[1] <= UDP_DST_PORT;
udp[2] <= UDP_HEADER_AND_DATA_LENGTH;
udp[3] <= UDP_CRC;
status <= STATUS_SEND_PRE;
end
STATUS_SEND_PRE : begin
led <= 4'b1000;
if (i < 4) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= pre
[15:12];
8'd1 : E_TXD <= pre[11:8];
8'd2 : E_TXD <= pre[7:4];
8'd3 : begin
E_TXD <= pre[3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_MAC;
i <= 0;
end
end
STATUS_SEND_MAC : begin
//led <= 4'b0010;
crc_en <= 1;
crc_rst <= 0;
if (i < 7) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= mac[15:12];
8'd1 : E_TXD <= mac[11:8];
8'd2 : E_TXD <= mac[7:4];
8'd3 : begin
E_TXD <= mac[3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_IP;
i <= 0;
end
end
STATUS_SEND_IP : begin
//led <= 4'b0001;
if (i < 10) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= ip[15:12];
8'd1 : E_TXD <= ip[11:8];
8'd2 : E_TXD <= ip[7:4];
8'd3 : begin
E_TXD <= ip[3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_UDP;
i <= 0;
end
end
STATUS_SEND_UDP : begin
if (i < 4) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= udp[15:12];
8'd1 : E_TXD <= udp[11:8];
8'd2 : E_TXD <= udp[7:4];
8'd3 : begin
E_TXD <= udp[3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_CRC;
i <= 0;
end
end
STATUS_SEND_CRC : begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= {~crc_out[28], ~crc_out[29], ~crc_out[30], ~crc_out[31]};
8'd1 : E_TXD <= {~crc_out[24], ~crc_out[25], ~crc_out[26], ~crc_out[27]};
8'd2 : E_TXD <= {~crc_out[20], ~crc_out[21], ~crc_out[22], ~crc_out[23]};
8'd3 : E_TXD <= {~crc_out[16], ~crc_out[17], ~crc_out[18], ~crc_out[19]};
8'd4 : E_TXD <= {~crc_out[12], ~crc_out[13], ~crc_out[14], ~crc_out[15]};
8'd5 : E_TXD <= {~crc_out[8], ~crc_out[9], ~crc_out[10], ~crc_out[11]};
8'd6 : E_TXD <= {~crc_out[4], ~crc_out[5], ~crc_out[6], ~crc_out[7]};
8'd7 : begin
E_TXD <= {~crc_out[0], ~crc_out[1], ~crc_out[2], ~crc_out[3]};
j <= 0;
status <= STATUS_IDLE;
end
endcase
end
endcase
end
end
endmodule
-------- CRC 校验模块 --------
module crc (clk, reset, data_in, en, crc_out, crc_next);
parameter Tp = 1;
input clk;
input reset;
input [7:0] data_in;
input en;
output [31:0] crc_out;
reg [31:0] crc_out;
output [31:0] crc_next;
wire [7:0] data;
assign data={data_in[0],data_in[1],data_in[2],data_in[3],data_in[4],data_in[5],data_in[6],data_in[7]};
assign crc_next[0] = crc_out[24] ^ crc_out[30] ^ data[0] ^ data[6];
assign crc_next[1] = crc_out[24] ^ crc_out[25] ^ crc_out[30] ^ crc_out[31] ^ data[0] ^ data[1] ^ data[6] ^ data[7];
assign crc_next[2] = crc_out[24] ^ crc_out[25] ^ crc_out[26] ^ crc_out[30] ^ crc_out[31] ^ data[0] ^ data[1] ^ data[2] ^ data[6] ^ data[7];
assign crc_next[3] = crc_out[25] ^ crc_out[26] ^ crc_out[27] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[3] ^ data[7];
assign crc_next[4] = crc_out[24] ^ crc_out[26] ^ crc_out[27] ^ crc_out[28] ^ crc_out[30] ^ data[0] ^ data[2] ^ data[3] ^ data[4] ^ data[6];
assign crc_next[5] = crc_out[24] ^ crc_out[25] ^ crc_out[27] ^ crc_out[28] ^ crc_out[29] ^ crc_out[30] ^ crc_out[31] ^ data[0] ^ data[1] ^ data[3] ^ data[4] ^ data[5] ^ data[6] ^ data[7];
assign crc_next[6] = crc_out[25] ^ crc_out[26] ^ crc_out[28] ^ crc_out[29] ^ crc_out[30] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[4] ^ data[5] ^ data[6] ^ data[7];
assign crc_next[7] = crc_out[24] ^ crc_out[26] ^ crc_out[27] ^ crc_out[29] ^ crc_out[31] ^ data[0] ^ data[2] ^ data[3] ^ data[5] ^ data[7];
assign crc_next[8] = crc_out[0] ^ crc_out[24] ^ crc_out[25] ^ crc_out[27] ^ crc_out[28] ^ data[0] ^ data[1] ^ data[3] ^ data[4];
assign crc_next[9] = crc_out[1] ^ crc_out[25] ^ crc_out[26] ^ crc_out[28] ^ crc_out[29] ^ data[1] ^ data[2] ^ data[4] ^ data[5];
assign crc_next[10] = crc_out[2] ^ crc_out[24] ^ crc_out[26] ^ crc_out[27] ^ crc_out[29] ^ data[0] ^ data[2] ^ data[3] ^ data[5];
assign crc_next[11] = crc_out[3] ^ crc_out[24] ^ crc_out[25] ^ crc_out[27] ^ crc_out[28] ^ data[0] ^ data[1] ^ data[3] ^ data[4];
assign crc_next[12] = crc_out[4] ^ crc_out[24] ^ crc_out[25] ^ crc_out[26] ^ crc_out[28] ^ crc_out[29] ^ crc_out[30] ^ data[0] ^ data[1] ^ data[2] ^ data[4] ^ data[5] ^ data[6];
assign crc_next[13] = crc_out[5] ^ crc_out[25] ^ crc_out[26] ^ crc_out[27] ^ crc_out[29] ^ crc_out[30] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[3] ^ data[5] ^ data[6] ^ data[7];
assign crc_next[14] = crc_out[6] ^ crc_out[26] ^ crc_out[27] ^ crc_out[28] ^ crc_out[30] ^ crc_out[31] ^ data[2] ^ data[3] ^ data[4] ^ data[6] ^ data[7];
assign crc_next[15] = crc_out[7] ^ crc_out[27] ^ crc_out[28] ^ crc_out[29] ^ crc_out[31] ^ data[3] ^ data[4] ^ data[5] ^ data[7];
assign crc_next[16] = crc_out[8] ^ crc_out[24] ^ crc_out[28] ^ crc_out[29] ^ data[0] ^ data[4] ^ data[5];
assign crc_next[17] = crc_out[9] ^ crc_out[25] ^ crc_out[29] ^ crc_out[30] ^ data[1] ^ data[5] ^ data[6];
assign crc_next[18] = crc_out[10] ^ crc_out[26] ^ crc_out[30] ^ crc_out[31] ^ data[2] ^ data[6] ^ data[7];
assign crc_next[19] = crc_out[11] ^ crc_out[27] ^ crc_out[31] ^ data[3] ^ data[7];
assign crc_next[20] = crc_out[12] ^ crc_out[28] ^ data[4];
assign crc_next[21] = crc_out[13] ^ crc_out[29] ^ data[5];
assign crc_next[22] = crc_out[14] ^ crc_out[24] ^ data[0];
assign crc_next[23] = crc_out[15] ^ crc_out[24] ^ crc_out[25] ^ crc_out[30] ^ data[0] ^ data[1] ^ data[6];
assign crc_next[24] = crc_out[16] ^ crc_out[25] ^ crc_out[26] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[7];
assign crc_next[25] = crc_out[17] ^ crc_out[26] ^ crc_out[27] ^ data[2] ^ data[3];
assign crc_next[26] = crc_out[18] ^ crc_out[24] ^ crc_out[27] ^ crc_out[28] ^ crc_out[30] ^ data[0] ^ data[3] ^ data[4] ^ data[6];
assign crc_next[27] = crc_out[19] ^ crc_out[25] ^ crc_out[28] ^ crc_out[29] ^ crc_out[31] ^ data[1] ^ data[4] ^ data[5] ^ data[7];
assign crc_next[28] = crc_out[20] ^ crc_out[26] ^ crc_out[29] ^ crc_out[30] ^ data[2] ^ data[5] ^ data[6];
assign crc_next[29] = crc_out[21] ^ crc_out[27] ^ crc_out[30] ^ crc_out[31] ^ data[3] ^ data[6] ^ data[7];
assign crc_next[30] = crc_out[22] ^ crc_out[28] ^ crc_out[31] ^ data[4] ^ data[7];
assign crc_next[31] = crc_out[23] ^ crc_out[29] ^ data[5];
always @ (posedge clk, posedge reset)
begin
if (reset) begin
crc_out <={32{1'b1}};
end
else if (en)
crc_out <=crc_next;
end
endmodule
求各位大神帮忙看看,非常感激!!