FPGA|CPLD|ASIC论坛
直播中

昌维

6年用户 18经验值
私信 关注
[问答]

我使用Verilog开发了一个以太网UDP通信,但是使用Wireshark无法抓取到FPGA发过来的任何包

我的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_OPtiOPN = 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

求各位大神帮忙看看,非常感激!!


回帖(2)

昌维

2019-5-16 23:14:05
除了CRC模块是网上抄的,其他都是我自己手写的,我自己也看了看以太网的通信协议,就是照着MAC,IP,UDP的封包格式来写的
举报

钱峰

2019-6-17 08:02:25
parameter MAC_PRE = 64'hd5_55_55_55_55_55_55_55; // pre code, required少了一个5
7 举报
  • 昌维: 我查了一下前导码确实是7组0x5 0x5和一组0x5 0xd啊,指的少了一个5是哪个位置啊?
  • 钱峰 回复 昌维: 我看错了。
  • 钱峰 回复 昌维: 有没有可能是PC机的设置问题?
  • 昌维 回复 钱峰: 請問PC機該如何設置啊?是有線網卡需要什麼設置嗎?因为我FPGA里面 MAC包的目的MAC是FF-FF-FF-FF-FF-FF,也就是广播地址,理论上无论PC是什么MAC都能收到吧?
  • 昌维 回复 钱峰: 我看PC上面有线网卡显示100Mbps已连接上,而且是全双工自动协商的
  • 钱峰 回复 昌维: 你把目的MAC地址换成PC机的。
  • 昌维 回复 钱峰: 换了,还是没用,哎。。。

更多回帖

发帖
×
20
完善资料,
赚取积分