TaterLi 个人博客

FPGA 网络通信实战 (verilog-ethernet)

以前对着各种教程手戳过轮子,不过由于架构各种看起来都不爽,然后一年多前其实移植过大佬的verilog-ethernet,但是跑完echo就放一边了,最近有一个实际要干的事情,所以又拿起来了.

这个主要是介绍,工程自己下载.

**图片很大,可以自行右键看原图**

我这里实现了很多功能,PicoRV32作为软核,软核主要和这4个外设通信.

其中BRAM是程序储存和运行内存,UART就是打印日志,定时器提供毫秒时间,MDIO就是网卡控制不用多解释.

MDIO通信是为了确定插入状态等,软核上实现函数.

static void mdio_write(uint32_t reg, uint32_t val16)
{
    uint32_t reg5 = reg & 0x1Fu;
    uint32_t val  = val16 & 0xFFFFu;

    // clear DONE/ERR (按你 Tcl)
    mmio_wr32(MDIO_REG0, 0x00008000u);

    uint32_t cmd =
        (val << 16) |
        (1u << 14) |
        (reg5 << 8) |
        (1u << 3);

    mmio_wr32(MDIO_REG0, cmd);

    // 原 Tcl after 1:等 1ms
    delay_ms(1);
}

static uint32_t mdio_read(uint32_t reg)
{
    uint32_t reg5 = reg & 0x1Fu;

    mmio_wr32(MDIO_REG0, 0x00008000u);

    uint32_t cmd =
        (1u << 14) |
        (1u << 13) |
        (reg5 << 8) |
        (1u << 3);

    mmio_wr32(MDIO_REG0, cmd);

    delay_ms(1);

    uint32_t w = mmio_rd32(MDIO_REG0);
    return (w >> 16) & 0xFFFFu;
}
```
软核完整实现,C和RTL在这里,不多说.

<a href="https://github.com/nickfox-taterli/picorv32_full">https://github.com/nickfox-taterli/picorv32_full</a>

网络这里,netcore是对接verilog-ethernet,中间插入fifo是为了不背压以太网,以及过滤坏包.udp_write_to_ddr是具体协议实现.协议在收包后ACK,COMMIT到DDR后再ACK.

当PC把包发送到后,软核可以读到内容.

#define DDR_BASE_ADDR  0x80000000

static void print_ddr_memory(void)
{
    volatile uint8_t *ddr_ptr = (volatile uint8_t*)DDR_BASE_ADDR;
    
    for (int i = 0; i < 16; i++) {
        uint8_t byte_val = ddr_ptr[i];
        
        // 打印高4位
        uint8_t high_nibble = (byte_val >> 4) & 0x0F;
        if (high_nibble < 10) {
            putc('0' + high_nibble);
        } else {
            putc('a' + (high_nibble - 10));
        }
        
        // 打印低4位
        uint8_t low_nibble = byte_val & 0x0F;
        if (low_nibble < 10) {
            putc('0' + low_nibble);
        } else {
            putc('a' + (low_nibble - 10));
        }
        
        // 打印空格(除了最后一个字节)
        if (i < 15) {
            putc(' ');
        }
    }
    putc('\r');
    putc('\n');
}

可见写入成功,内容对的上.

完整代码 https://github.com/nickfox-taterli/FPGA-Net-To-DDR

退出移动版