diff options
author | Johnathan Corgan | 2009-08-31 12:08:30 -0700 |
---|---|---|
committer | Johnathan Corgan | 2009-08-31 12:08:30 -0700 |
commit | 7eea883c377f64862a4d83f1b33a83fdf3cfc392 (patch) | |
tree | 2c4b4d32c28e331cea42b16e001e89a74eb3b3e2 | |
parent | 1aa216df204197b4849581dd4f42b2e7680eb72f (diff) | |
download | gnuradio-7eea883c377f64862a4d83f1b33a83fdf3cfc392.tar.gz gnuradio-7eea883c377f64862a4d83f1b33a83fdf3cfc392.tar.bz2 gnuradio-7eea883c377f64862a4d83f1b33a83fdf3cfc392.zip |
Merged SVN matt/new_eth r10782:11633 into new_eth
* svn diff http://gnuradio.org/svn/branches/developers/matt/new_eth
-r10782:11633
* Patch applied with no conflicts or fuzz.
30 files changed, 739 insertions, 1034 deletions
diff --git a/usrp2/firmware/apps/gen_eth_packets.c b/usrp2/firmware/apps/gen_eth_packets.c index ce1e8160b..b81f60dac 100644 --- a/usrp2/firmware/apps/gen_eth_packets.c +++ b/usrp2/firmware/apps/gen_eth_packets.c @@ -141,11 +141,12 @@ main(void) ethernet_register_link_changed_callback(link_changed_callback); ethernet_init(); + /* if (hwconfig_simulation_p()){ eth_mac->speed = 4; // hardcode mac speed to 1000 link_is_up = true; } - + */ // fire off a receive from the ethernet bp_receive_to_buf(CPU_RX_BUF, PORT_ETH, 1, 0, BP_LAST_LINE); diff --git a/usrp2/firmware/apps/txrx.c b/usrp2/firmware/apps/txrx.c index 730ee66c5..935e62a72 100644 --- a/usrp2/firmware/apps/txrx.c +++ b/usrp2/firmware/apps/txrx.c @@ -257,12 +257,14 @@ main(void) { u2_init(); - putstr("\nTxRx\n"); + putstr("\nTxRx-NEWETH\n"); print_mac_addr(ethernet_mac_addr()->addr); newline(); ethernet_register_link_changed_callback(link_changed_callback); + putstr("Before ethernet_init()\n"); ethernet_init(); + putstr("After ethernet_init()\n"); #if 0 diff --git a/usrp2/firmware/lib/eth_mac.c b/usrp2/firmware/lib/eth_mac.c index 5fadaf40b..41690af95 100644 --- a/usrp2/firmware/lib/eth_mac.c +++ b/usrp2/firmware/lib/eth_mac.c @@ -21,7 +21,7 @@ #include "bool.h" #include "eth_phy.h" // for simulation constants #include "mdelay.h" - +#include "stdio.h" #define PHY_ADDR 1 @@ -29,7 +29,11 @@ void eth_mac_set_addr(const u2_mac_addr_t *src) { int i; - + eth_mac->ucast_hi = ((unsigned int)src->addr[0])<<8 + ((unsigned int)src->addr[1]); + eth_mac->ucast_lo = ((unsigned int)src->addr[2])<<24 + ((unsigned int)src->addr[3])<<16 + + ((unsigned int)src->addr[4])<<8 +((unsigned int)src->addr[5]); + + /* // tell mac our source address and enable automatic insertion on Tx. eth_mac->mac_tx_add_prom_wr = 0; // just in case for (i = 0; i < 6; i++){ @@ -53,6 +57,8 @@ eth_mac_set_addr(const u2_mac_addr_t *src) mdelay(1); } // eth_mac->mac_rx_add_chk_en = 1; // FIXME enable when everything's working + + */ } @@ -62,14 +68,14 @@ eth_mac_init(const u2_mac_addr_t *src) eth_mac->miimoder = 25; // divider from CPU clock (50MHz/25 = 2MHz) eth_mac_set_addr(src); - + eth_mac->settings = 0x39; // set rx flow control high and low water marks // unsigned int lwmark = (2*2048 + 64)/4; // 2 * 2048-byte frames + 1 * 64-byte pause frame // eth_mac->fc_hwmark = lwmark + 2048/4; // plus a 2048-byte frame - eth_mac->fc_lwmark = 600; // there are currently 2047 lines in the fifo - eth_mac->fc_hwmark = 1200; - eth_mac->fc_padtime = 1700; // how long before flow control runs out do we + // eth_mac->fc_lwmark = 600; // there are currently 2047 lines in the fifo + // eth_mac->fc_hwmark = 1200; + //eth_mac->fc_padtime = 1700; // how long before flow control runs out do we // request a re-pause. Units of 8ns (bytes) //eth_mac->tx_pause_en = 0; // pay attn to pause frames sent to us @@ -80,8 +86,8 @@ eth_mac_init(const u2_mac_addr_t *src) int eth_mac_read_rmon(int addr) { - int t; - + int t = 0; + /* eth_mac->rmon_rd_addr = addr; eth_mac->rmon_rd_apply = 1; while(eth_mac->rmon_rd_grant == 0) @@ -89,6 +95,7 @@ eth_mac_read_rmon(int addr) t = eth_mac->rmon_rd_dout; eth_mac->rmon_rd_apply = 0; + */ return t; } @@ -111,6 +118,7 @@ eth_mac_miim_read(int addr) while((eth_mac->miistatus & MIIS_BUSY) != 0) ; + printf("MIIM-READ ADDR %d DATA %d\n",addr, eth_mac->miirx_data); return eth_mac->miirx_data; } @@ -122,6 +130,7 @@ eth_mac_miim_write(int addr, int value) eth_mac->miitx_data = value; eth_mac->miicommand = MIIC_WCTRLDATA; + printf("MIIM-WRITE ADDR %d VAL %d\n",addr,value); while((eth_mac->miistatus & MIIS_BUSY) != 0) ; } diff --git a/usrp2/firmware/lib/eth_mac_regs.h b/usrp2/firmware/lib/eth_mac_regs.h index 8daab937d..3c866e471 100644 --- a/usrp2/firmware/lib/eth_mac_regs.h +++ b/usrp2/firmware/lib/eth_mac_regs.h @@ -20,68 +20,21 @@ #define INCLUDED_ETH_MAC_REGS_H /* - * See opencores.org 10_100_1000 Mbps Tri-mode Ethernet MAC Specification + * Simple GEMAC * - * In reality, these are 16-bit regs, but are assigned - * on 32-bit boundaries. Because we're little endian, - * declaring them "int" works. */ typedef struct { - volatile int tx_hwmark; - volatile int tx_lwmark; - - //! if set, send pause frames automatically - volatile int pause_frame_send_en; - - //! quanta value for pause frame in units of 512 bit times. - volatile int pause_quanta_set; - - volatile int ifg_set; - volatile int full_duplex; - volatile int max_retry; - volatile int mac_tx_add_en; - volatile int mac_tx_add_prom_data; - volatile int mac_tx_add_prom_add; - volatile int mac_tx_add_prom_wr; - - //! if set, other end can pause us (i.e., we pay attention to pause frames) - volatile int tx_pause_en; - - // Flow Control high and low water marks - //! when space available (in 32-bit lines) > hwmark, send un-pause frame - volatile int fc_hwmark; - - //! when space avail (in 32-bit lines) < lwmark, send pause frame - volatile int fc_lwmark; - - volatile int mac_rx_add_chk_en; - volatile int mac_rx_add_prom_data; - volatile int mac_rx_add_prom_add; - volatile int mac_rx_add_prom_wr; - volatile int broadcast_filter_en; - volatile int broadcast_bucket_depth; - volatile int broadcast_bucket_interval; - volatile int rx_append_crc; - volatile int rx_hwmark; - volatile int rx_lwmark; - volatile int crc_chk_en; - volatile int rx_ifg_set; - volatile int rx_max_length; - volatile int rx_min_length; - volatile int rmon_rd_addr; // performance counter access - volatile int rmon_rd_apply; - volatile int rmon_rd_grant; // READONLY - volatile int rmon_rd_dout; // READONLY - volatile int dummy; // READONLY - volatile int line_loop_en; - volatile int speed; - volatile int miimoder; - volatile int miicommand; - volatile int miiaddress; - volatile int miitx_data; - volatile int miirx_data; - volatile int miistatus; - volatile int fc_padtime; + volatile int settings; + volatile int ucast_hi; + volatile int ucast_lo; + volatile int mcast_hi; + volatile int mcast_lo; + volatile int miimoder; + volatile int miiaddress; + volatile int miitx_data; + volatile int miicommand; + volatile int miistatus; + volatile int miirx_data; } eth_mac_regs_t; // miicommand register diff --git a/usrp2/firmware/lib/ethernet.c b/usrp2/firmware/lib/ethernet.c index d19287044..32d2e39bd 100644 --- a/usrp2/firmware/lib/ethernet.c +++ b/usrp2/firmware/lib/ethernet.c @@ -43,6 +43,8 @@ ethernet_register_link_changed_callback(ethernet_link_changed_callback_t new_cal static void ed_set_mac_speed(int speed) { + printf("Speed set to %d\n",speed); + /* switch(speed){ case 10: eth_mac->speed = 1; @@ -56,6 +58,7 @@ ed_set_mac_speed(int speed) default: break; } + */ } static void @@ -196,17 +199,17 @@ ethernet_init(void) ed_state.link_speed = S_UNKNOWN; // initialize MAC registers - eth_mac->tx_hwmark = 0x1e; - eth_mac->tx_lwmark = 0x19; + // eth_mac->tx_hwmark = 0x1e; + //eth_mac->tx_lwmark = 0x19; - eth_mac->crc_chk_en = 1; - eth_mac->rx_max_length = 2048; + //eth_mac->crc_chk_en = 1; + //eth_mac->rx_max_length = 2048; // configure PAUSE frame stuff - eth_mac->tx_pause_en = 1; // pay attn to pause frames sent to us + //eth_mac->tx_pause_en = 1; // pay attn to pause frames sent to us - eth_mac->pause_quanta_set = 38; // a bit more than 1 max frame 16kb/512 + fudge - eth_mac->pause_frame_send_en = 1; // enable sending pause frames + //eth_mac->pause_quanta_set = 38; // a bit more than 1 max frame 16kb/512 + fudge + //eth_mac->pause_frame_send_en = 1; // enable sending pause frames // setup PHY to interrupt on changes @@ -322,6 +325,7 @@ ethernet_check_errors(void) // these registers are reset when read int r = 0; + /* if (eth_mac_read_rmon(0x05) != 0) r |= RME_RX_CRC; if (eth_mac_read_rmon(0x06) != 0) @@ -335,6 +339,6 @@ ethernet_check_errors(void) r |= RME_TX_FIFO_UNDER; if (eth_mac_read_rmon(0x27) != 0) r |= RME_TX_FIFO_OVER; - + */ return r; } diff --git a/usrp2/fpga/control_lib/buffer_int.v b/usrp2/fpga/control_lib/buffer_int.v index c33f2779d..e69de29bb 100644 --- a/usrp2/fpga/control_lib/buffer_int.v +++ b/usrp2/fpga/control_lib/buffer_int.v @@ -1,251 +0,0 @@ - -// FIFO Interface to the 2K buffer RAMs -// Read port is read-acknowledge -// FIXME do we want to be able to interleave reads and writes? - -module buffer_int - #(parameter BUFF_NUM = 0) - (// Control Interface - input clk, - input rst, - input [31:0] ctrl_word, - input go, - output done, - output error, - output idle, - - // Buffer Interface - output en_o, - output we_o, - output reg [8:0] addr_o, - output [31:0] dat_to_buf, - input [31:0] dat_from_buf, - - // Write FIFO Interface - input [31:0] wr_dat_i, - input wr_write_i, - input wr_done_i, - input wr_error_i, - output reg wr_ready_o, - output reg wr_full_o, - - // Read FIFO Interface - output [31:0] rd_dat_o, - input rd_read_i, - input rd_done_i, - input rd_error_i, - output reg rd_sop_o, - output reg rd_eop_o - ); - - reg [31:0] ctrl_reg; - reg go_reg; - - always @(posedge clk) - go_reg <= go; - - always @(posedge clk) - if(rst) - ctrl_reg <= 0; - else - if(go & (ctrl_word[31:28] == BUFF_NUM)) - ctrl_reg <= ctrl_word; - - wire [8:0] firstline = ctrl_reg[8:0]; - wire [8:0] lastline = ctrl_reg[17:9]; - wire [3:0] step = ctrl_reg[21:18]; - wire read = ctrl_reg[22]; - wire write = ctrl_reg[23]; - wire clear = ctrl_reg[24]; - //wire [2:0] port = ctrl_reg[27:25]; // Ignored in this block - //wire [3:0] buff_num = ctrl_reg[31:28]; // Ignored here ? - - assign dat_to_buf = wr_dat_i; - assign rd_dat_o = dat_from_buf; - - localparam IDLE = 3'd0; - localparam PRE_READ = 3'd1; - localparam READING = 3'd2; - localparam WRITING = 3'd3; - localparam ERROR = 3'd4; - localparam DONE = 3'd5; - - reg [2:0] state; - - always @(posedge clk) - if(rst) - begin - state <= IDLE; - rd_sop_o <= 0; - rd_eop_o <= 0; - wr_ready_o <= 0; - wr_full_o <= 0; - end - else - if(clear) - begin - state <= IDLE; - rd_sop_o <= 0; - rd_eop_o <= 0; - wr_ready_o <= 0; - wr_full_o <= 0; - end - else - case(state) - IDLE : - if(go_reg & read) - begin - addr_o <= firstline; - state <= PRE_READ; - end - else if(go_reg & write) - begin - addr_o <= firstline; - state <= WRITING; - wr_ready_o <= 1; - end - - PRE_READ : - begin - state <= READING; - addr_o <= addr_o + 1; - rd_sop_o <= 1; - end - - READING : - if(rd_error_i) - state <= ERROR; - else if(rd_done_i) - state <= DONE; - else if(rd_read_i) - begin - rd_sop_o <= 0; - addr_o <= addr_o + 1; - if(addr_o == lastline) - rd_eop_o <= 1; - else - rd_eop_o <= 0; - if(rd_eop_o) - state <= DONE; - end - - WRITING : - begin - if(wr_write_i) - addr_o <= addr_o + 1; // This was the timing problem, so now it doesn't depend on wr_error_i - if(wr_error_i) - begin - state <= ERROR; - wr_ready_o <= 0; - end - else - begin - if(wr_write_i) - begin - wr_ready_o <= 0; - if(addr_o == (lastline-1)) - wr_full_o <= 1; - if(addr_o == lastline) - state <= DONE; - end - if(wr_done_i) - begin - state <= DONE; - wr_ready_o <= 0; - end - end // else: !if(wr_error_i) - end // case: WRITING - - DONE : - begin - rd_eop_o <= 0; - rd_sop_o <= 0; - wr_ready_o <= 0; - wr_full_o <= 0; - end - - endcase // case(state) - - // FIXME ignores step for now - - assign we_o = (state == WRITING) && wr_write_i; // FIXME potential critical path - // IF this is a timing problem, we could always write when in this state - assign en_o = ~((state==READING)& ~rd_read_i); // FIXME potential critical path - - assign done = (state == DONE); - assign error = (state == ERROR); - assign idle = (state == IDLE); -endmodule // buffer_int - - - -// These are 2 other ways for doing the WRITING state, both work. First one is faster, but confusing -/* - begin - // Gen 4 values -- state, wr_ready_o, addr_o, wr_full_o - if(~wr_error_i & wr_write_i & (addr_o == (lastline-1))) - wr_full_o <= 1; - if(wr_error_i | wr_write_i | wr_done_i) - wr_ready_o <= 0; - if(wr_error_i) - state <= ERROR; - else if(wr_done_i | (wr_write_i & (addr_o == lastline))) - state <= DONE; - // This one was the timing problem... now we increment addr_o even if there is an error - if(wr_write_i) - addr_o <= addr_o + 1; - end // case: WRITING -*/ - -/* begin - if(wr_error_i) - begin - state <= ERROR; - wr_ready_o <= 0; - end - else - begin - if(wr_write_i) - begin - wr_ready_o <= 0; - addr_o <= addr_o + 1; - if(addr_o == (lastline-1)) - wr_full_o <= 1; - if(addr_o == lastline) - state <= DONE; - end - if(wr_done_i) - begin - state <= DONE; - wr_ready_o <= 0; - end - end // else: !if(wr_error_i) - end // case: WRITING -*/ - - - - - - - - - - - - - - -// Unused old code - //assign rd_empty_o = (state != READING); // && (state != PRE_READ); - //assign rd_empty_o = rd_empty_reg; // timing fix? - //assign rd_ready_o = (state == READING); - //assign rd_ready_o = ~rd_empty_reg; // timing fix? - - //wire rd_en = (state == PRE_READ) || ((state == READING) && rd_read_i); - //wire wr_en = (state == WRITING) && wr_write_i; // IF this is a timing problem, we could always enable when in this state - //assign en_o = rd_en | wr_en; - - // assign wr_full_o = (state != WRITING); - // assign wr_ready_o = (state == WRITING); - diff --git a/usrp2/fpga/control_lib/buffer_pool.v b/usrp2/fpga/control_lib/buffer_pool.v index 969296230..e69de29bb 100644 --- a/usrp2/fpga/control_lib/buffer_pool.v +++ b/usrp2/fpga/control_lib/buffer_pool.v @@ -1,323 +0,0 @@ - -// Buffer pool. Contains 8 buffers, each 2K (512 by 32). Each buffer -// is a dual-ported RAM. Port A on each of them is indirectly connected -// to the wishbone bus by a bridge. Port B may be connected any one of the -// 8 (4 rd, 4 wr) FIFO-like streaming interaces, or disconnected. The wishbone bus -// provides access to all 8 buffers, and also controls the connections -// between the ports and the buffers, allocating them as needed. - -// wb_adr is 16 bits -- -// bits 13:11 select which buffer -// bits 10:2 select line in buffer -// bits 1:0 are unused (32-bit access only) - -module buffer_pool - (input wb_clk_i, - input wb_rst_i, - input wb_we_i, - input wb_stb_i, - input [15:0] wb_adr_i, - input [31:0] wb_dat_i, - output [31:0] wb_dat_o, - output reg wb_ack_o, - output wb_err_o, - output wb_rty_o, - - input stream_clk, - input stream_rst, - - input set_stb, input [7:0] set_addr, input [31:0] set_data, - output [31:0] status, - output sys_int_o, - - output [31:0] s0, output [31:0] s1, output [31:0] s2, output [31:0] s3, - output [31:0] s4, output [31:0] s5, output [31:0] s6, output [31:0] s7, - - // Write Interfaces - input [31:0] wr0_dat_i, input wr0_write_i, input wr0_done_i, input wr0_error_i, output wr0_ready_o, output wr0_full_o, - input [31:0] wr1_dat_i, input wr1_write_i, input wr1_done_i, input wr1_error_i, output wr1_ready_o, output wr1_full_o, - input [31:0] wr2_dat_i, input wr2_write_i, input wr2_done_i, input wr2_error_i, output wr2_ready_o, output wr2_full_o, - input [31:0] wr3_dat_i, input wr3_write_i, input wr3_done_i, input wr3_error_i, output wr3_ready_o, output wr3_full_o, - - // Read Interfaces - output [31:0] rd0_dat_o, input rd0_read_i, input rd0_done_i, input rd0_error_i, output rd0_sop_o, output rd0_eop_o, - output [31:0] rd1_dat_o, input rd1_read_i, input rd1_done_i, input rd1_error_i, output rd1_sop_o, output rd1_eop_o, - output [31:0] rd2_dat_o, input rd2_read_i, input rd2_done_i, input rd2_error_i, output rd2_sop_o, output rd2_eop_o, - output [31:0] rd3_dat_o, input rd3_read_i, input rd3_done_i, input rd3_error_i, output rd3_sop_o, output rd3_eop_o - ); - - wire [7:0] sel_a; - - wire [2:0] which_buf = wb_adr_i[13:11]; // address 15:14 selects the buffer pool - wire [8:0] buf_addra = wb_adr_i[10:2]; // ignore address 1:0, 32-bit access only - - decoder_3_8 dec(.sel(which_buf),.res(sel_a)); - - genvar i; - - wire go; - - reg [2:0] port[0:7]; - reg [3:0] read_src[0:3]; - reg [3:0] write_src[0:3]; - - wire [7:0] done; - wire [7:0] error; - wire [7:0] idle; - - wire [31:0] buf_doa[0:7]; - - wire [7:0] buf_enb; - wire [7:0] buf_web; - wire [8:0] buf_addrb[0:7]; - wire [31:0] buf_dib[0:7]; - wire [31:0] buf_dob[0:7]; - - wire [31:0] wr_dat_i[0:7]; - wire [7:0] wr_write_i; - wire [7:0] wr_done_i; - wire [7:0] wr_error_i; - wire [7:0] wr_ready_o; - wire [7:0] wr_full_o; - - wire [31:0] rd_dat_o[0:7]; - wire [7:0] rd_read_i; - wire [7:0] rd_done_i; - wire [7:0] rd_error_i; - wire [7:0] rd_sop_o; - wire [7:0] rd_eop_o; - - assign status = {8'd0,idle[7:0],error[7:0],done[7:0]}; - - assign s0 = {23'd0,buf_addrb[0]}; - assign s1 = {23'd0,buf_addrb[1]}; - assign s2 = {23'd0,buf_addrb[2]}; - assign s3 = {23'd0,buf_addrb[3]}; - assign s4 = {23'd0,buf_addrb[4]}; - assign s5 = {23'd0,buf_addrb[5]}; - assign s6 = {23'd0,buf_addrb[6]}; - assign s7 = {23'd0,buf_addrb[7]}; - - wire [31:0] fifo_ctrl; - setting_reg #(.my_addr(64)) - sreg(.clk(stream_clk),.rst(stream_rst),.strobe(set_stb),.addr(set_addr),.in(set_data), - .out(fifo_ctrl),.changed(go)); - - integer k; - always @(posedge stream_clk) - if(stream_rst) - for(k=0;k<8;k=k+1) - port[k] <= 4; // disabled - else - for(k=0;k<8;k=k+1) - if(go & (fifo_ctrl[31:28]==k)) - port[k] <= fifo_ctrl[27:25]; - - always @(posedge stream_clk) - if(stream_rst) - for(k=0;k<4;k=k+1) - read_src[k] <= 8; // disabled - else - for(k=0;k<4;k=k+1) - if(go & fifo_ctrl[22] & (fifo_ctrl[27:25]==k)) - read_src[k] <= fifo_ctrl[31:28]; - - always @(posedge stream_clk) - if(stream_rst) - for(k=0;k<4;k=k+1) - write_src[k] <= 8; // disabled - else - for(k=0;k<4;k=k+1) - if(go & fifo_ctrl[23] & (fifo_ctrl[27:25]==k)) - write_src[k] <= fifo_ctrl[31:28]; - - generate - for(i=0;i<8;i=i+1) - begin : gen_buffer - RAMB16_S36_S36 dpram - (.DOA(buf_doa[i]),.ADDRA(buf_addra),.CLKA(wb_clk_i),.DIA(wb_dat_i),.DIPA(4'h0), - .ENA(wb_stb_i & sel_a[i]),.SSRA(0),.WEA(wb_we_i), - .DOB(buf_dob[i]),.ADDRB(buf_addrb[i]),.CLKB(stream_clk),.DIB(buf_dib[i]),.DIPB(4'h0), - .ENB(buf_enb[i]),.SSRB(0),.WEB(buf_web[i]) ); - - /* ram_2port #(.DWIDTH(32),.AWIDTH(9)) buffer - (.clka(wb_clk_i),.ena(wb_stb_i & sel_a[i]),.wea(wb_we_i), - .addra(buf_addra),.dia(wb_dat_i),.doa(buf_doa[i]), - .clkb(stream_clk),.enb(buf_enb[i]),.web(buf_web[i]), - .addrb(buf_addrb[i]),.dib(buf_dib[i]),.dob(buf_dob[i])); */ - - buffer_int #(.BUFF_NUM(i)) fifo_int - (.clk(stream_clk),.rst(stream_rst), - .ctrl_word(fifo_ctrl),.go(go & (fifo_ctrl[31:28]==i)), - .done(done[i]),.error(error[i]),.idle(idle[i]), - .en_o(buf_enb[i]), - .we_o(buf_web[i]), - .addr_o(buf_addrb[i]), - .dat_to_buf(buf_dib[i]), - .dat_from_buf(buf_dob[i]), - .wr_dat_i(wr_dat_i[i]), - .wr_write_i(wr_write_i[i]), - .wr_done_i(wr_done_i[i]), - .wr_error_i(wr_error_i[i]), - .wr_ready_o(wr_ready_o[i]), - .wr_full_o(wr_full_o[i]), - .rd_dat_o(rd_dat_o[i]), - .rd_read_i(rd_read_i[i]), - .rd_done_i(rd_done_i[i]), - .rd_error_i(rd_error_i[i]), - .rd_sop_o(rd_sop_o[i]), - .rd_eop_o(rd_eop_o[i]) - ); - - // FIXME -- if it is a problem, maybe we don't need enables on these muxes - mux4 #(.WIDTH(32)) - mux4_dat_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_dat_i),.i1(wr1_dat_i), - .i2(wr2_dat_i),.i3(wr3_dat_i),.o(wr_dat_i[i])); - mux4 #(.WIDTH(1)) - mux4_write_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_write_i),.i1(wr1_write_i), - .i2(wr2_write_i),.i3(wr3_write_i),.o(wr_write_i[i])); - mux4 #(.WIDTH(1)) - mux4_wrdone_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_done_i),.i1(wr1_done_i), - .i2(wr2_done_i),.i3(wr3_done_i),.o(wr_done_i[i])); - mux4 #(.WIDTH(1)) - mux4_wrerror_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_error_i),.i1(wr1_error_i), - .i2(wr2_error_i),.i3(wr3_error_i),.o(wr_error_i[i])); - mux4 #(.WIDTH(1)) - mux4_read_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_read_i),.i1(rd1_read_i), - .i2(rd2_read_i),.i3(rd3_read_i),.o(rd_read_i[i])); - mux4 #(.WIDTH(1)) - mux4_rddone_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_done_i),.i1(rd1_done_i), - .i2(rd2_done_i),.i3(rd3_done_i),.o(rd_done_i[i])); - mux4 #(.WIDTH(1)) - mux4_rderror_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_error_i),.i1(rd1_error_i), - .i2(rd2_error_i),.i3(rd3_error_i),.o(rd_error_i[i])); - end // block: gen_buffer - endgenerate - - //---------------------------------------------------------------------- - // Wishbone Outputs - - // Use the following lines if ram output and mux can be made fast enough - - assign wb_err_o = 1'b0; // Unused for now - assign wb_rty_o = 1'b0; // Unused for now - - always @(posedge wb_clk_i) - wb_ack_o <= wb_stb_i & ~wb_ack_o; - assign wb_dat_o = buf_doa[which_buf]; - - // Use this if we can't make the RAM+MUX fast enough - // reg [31:0] wb_dat_o_reg; - // reg stb_d1; - - // always @(posedge wb_clk_i) - // begin - // wb_dat_o_reg <= buf_doa[which_buf]; - // stb_d1 <= wb_stb_i; - // wb_ack_o <= (stb_d1 & ~wb_ack_o) | (wb_we_i & wb_stb_i); - // end - //assign wb_dat_o = wb_dat_o_reg; - - mux8 #(.WIDTH(1)) - mux8_wr_ready0(.en(~write_src[0][3]),.sel(write_src[0][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), - .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]), - .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr0_ready_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_full0(.en(~write_src[0][3]),.sel(write_src[0][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr0_full_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_ready1(.en(~write_src[1][3]),.sel(write_src[1][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), - .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]), - .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr1_ready_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_full1(.en(~write_src[1][3]),.sel(write_src[1][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr1_full_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_ready2(.en(~write_src[2][3]),.sel(write_src[2][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), - .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]), - .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr2_ready_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_full2(.en(~write_src[2][3]),.sel(write_src[2][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr2_full_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_ready3(.en(~write_src[3][3]),.sel(write_src[3][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), - .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]), - .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr3_ready_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_full3(.en(~write_src[3][3]),.sel(write_src[3][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr3_full_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop0(.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd0_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop0(.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd0_eop_o)); - - mux8 #(.WIDTH(32)) - mux8_rd_dat_0 (.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd0_dat_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop1(.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd1_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop1(.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd1_eop_o)); - - mux8 #(.WIDTH(32)) - mux8_rd_dat_1 (.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd1_dat_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop2(.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd2_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop2(.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd2_eop_o)); - - mux8 #(.WIDTH(32)) - mux8_rd_dat_2 (.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd2_dat_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop3(.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd3_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop3(.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd3_eop_o)); - - mux8 #(.WIDTH(32)) - mux8_rd_dat_3 (.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd3_dat_o)); - - assign sys_int_o = (|error) | (|done); - -endmodule // buffer_pool diff --git a/usrp2/fpga/control_lib/newfifo/cascadefifo_2clock.v b/usrp2/fpga/control_lib/newfifo/cascadefifo_2clock.v new file mode 100644 index 000000000..2abbbf3b5 --- /dev/null +++ b/usrp2/fpga/control_lib/newfifo/cascadefifo_2clock.v @@ -0,0 +1,27 @@ + +module cascadefifo_2clock + #(parameter DWIDTH=32, AWIDTH=9) + (input wclk, input [DWIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, output [AWIDTH-1:0] level_wclk, + input rclk, output [DWIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, output [AWIDTH-1:0] level_rclk, + input arst); + + wire [DWIDTH-1:0] data_int1, data_int2; + wire src_rdy_int1, src_rdy_int2, dst_rdy_int1, dst_rdy_int2; + + fifo_short #(.WIDTH(DWIDTH)) shortfifo + (.clk(wclk), .reset(arst), .clear(0), + .datain(datain), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), + .dataout(data_int1), .src_rdy_o(src_rdy_int1), .dst_rdy_i(dst_rdy_int1) ); + + newfifo_2clock #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) fifo_2clock + (.wclk(wclk), .datain(data_int1), .src_rdy_i(src_rdy_int1), .dst_rdy_o(dst_rdy_int1), .level_wclk(level_wclk), + .rclk(rclk), .dataout(data_int2), .src_rdy_o(src_rdy_int2), .dst_rdy_i(dst_rdy_int2), .level_rclk(level_rclk), + .arst(arst) ); + + fifo_short #(.WIDTH(DWIDTH)) shortfifo2 + (.clk(rclk), .reset(arst), .clear(0), + .datain(data_int2), .src_rdy_i(src_rdy_int2), .dst_rdy_o(dst_rdy_int2), + .dataout(dataout), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i) ); + +endmodule // fifo_2clock_casc + diff --git a/usrp2/fpga/control_lib/newfifo/fifo36_to_ll8.v b/usrp2/fpga/control_lib/newfifo/fifo36_to_ll8.v index 1befb9e6e..0dee1dfc6 100644 --- a/usrp2/fpga/control_lib/newfifo/fifo36_to_ll8.v +++ b/usrp2/fpga/control_lib/newfifo/fifo36_to_ll8.v @@ -1,6 +1,6 @@ module fifo36_to_ll8 - (input clk, reset, + (input clk, input reset, input clear, input [35:0] f36_data, input f36_src_rdy_i, output f36_dst_rdy_o, diff --git a/usrp2/fpga/control_lib/newfifo/fifo_2clock.v b/usrp2/fpga/control_lib/newfifo/fifo_2clock.v index 6b1eb607e..e69de29bb 100644 --- a/usrp2/fpga/control_lib/newfifo/fifo_2clock.v +++ b/usrp2/fpga/control_lib/newfifo/fifo_2clock.v @@ -1,66 +0,0 @@ - -module fifo_2clock - #(parameter DWIDTH=32, AWIDTH=9) - (input wclk, input [DWIDTH-1:0] datain, input write, output full, output reg [AWIDTH-1:0] level_wclk, - input rclk, output [DWIDTH-1:0] dataout, input read, output empty, output reg [AWIDTH-1:0] level_rclk, - input arst); - - reg [AWIDTH-1:0] wr_addr, rd_addr; - wire [AWIDTH-1:0] wr_addr_rclk, rd_addr_wclk; - wire [AWIDTH-1:0] next_rd_addr; - wire enb_read; - - // Write side management - wire [AWIDTH-1:0] next_wr_addr = wr_addr + 1; - always @(posedge wclk or posedge arst) - if(arst) - wr_addr <= 0; - else if(write) - wr_addr <= next_wr_addr; - assign full = (next_wr_addr == rd_addr_wclk); - - // RAM for data storage. Data out is registered, complicating the - // read side logic - ram_2port #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) mac_rx_ff_ram - (.clka(wclk),.ena(1'b1),.wea(write),.addra(wr_addr),.dia(datain),.doa(), - .clkb(rclk),.enb(enb_read),.web(1'b0),.addrb(next_rd_addr),.dib(0),.dob(dataout) ); - - // Read side management - reg data_valid; - assign empty = ~data_valid; - assign next_rd_addr = rd_addr + data_valid; - assign enb_read = read | ~data_valid; - - always @(posedge rclk or posedge arst) - if(arst) - rd_addr <= 0; - else if(read) - rd_addr <= rd_addr + 1; - - always @(posedge rclk or posedge arst) - if(arst) - data_valid <= 0; - else - if(read & (next_rd_addr == wr_addr_rclk)) - data_valid <= 0; - else if(next_rd_addr != wr_addr_rclk) - data_valid <= 1; - - // Send pointers across clock domains via gray code - gray_send #(.WIDTH(AWIDTH)) send_wr_addr - (.clk_in(wclk),.addr_in(wr_addr), - .clk_out(rclk),.addr_out(wr_addr_rclk) ); - - gray_send #(.WIDTH(AWIDTH)) send_rd_addr - (.clk_in(rclk),.addr_in(rd_addr), - .clk_out(wclk),.addr_out(rd_addr_wclk) ); - - // Generate fullness info, these are approximate and may be delayed - // and are only for higher-level flow control. - // Only full and empty are guaranteed exact. - always @(posedge wclk) - level_wclk <= wr_addr - rd_addr_wclk; - always @(posedge rclk) - level_rclk <= wr_addr_rclk - rd_addr; - -endmodule // fifo_2clock diff --git a/usrp2/fpga/control_lib/newfifo/fifo_2clock_casc.v b/usrp2/fpga/control_lib/newfifo/fifo_2clock_casc.v index e9b0cfc25..e69de29bb 100644 --- a/usrp2/fpga/control_lib/newfifo/fifo_2clock_casc.v +++ b/usrp2/fpga/control_lib/newfifo/fifo_2clock_casc.v @@ -1,31 +0,0 @@ - -module fifo_2clock_casc - #(parameter DWIDTH=32, AWIDTH=9) - (input wclk, input [DWIDTH-1:0] datain, input write, output full, output [AWIDTH-1:0] level_wclk, - input rclk, output [DWIDTH-1:0] dataout, input read, output empty, output [AWIDTH-1:0] level_rclk, - input arst); - - wire full_int, empty_int, full_int2, empty_int2, transfer, transfer2; - wire [DWIDTH-1:0] data_int, data_int2; - - shortfifo #(.WIDTH(DWIDTH)) shortfifo - (.clk(wclk), .rst(arst), .clear(0), - .datain(datain), .write(write), .full(full), - .dataout(data_int), .read(transfer), .empty(empty_int) ); - - assign transfer = ~full_int & ~empty_int; - - fifo_2clock #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) fifo_2clock - (.wclk(wclk), .datain(data_int), .write(transfer), .full(full_int), .level_wclk(level_wclk), - .rclk(rclk), .dataout(data_int2), .read(transfer2), .empty(empty_int2), .level_rclk(level_rclk), - .arst(arst) ); - - assign transfer2 = ~full_int2 & ~empty_int2; - - shortfifo #(.WIDTH(DWIDTH)) shortfifo2 - (.clk(rclk), .rst(arst), .clear(0), - .datain(data_int2), .write(transfer2), .full(full_int2), - .dataout(dataout), .read(read), .empty(empty) ); - -endmodule // fifo_2clock_casc - diff --git a/usrp2/fpga/control_lib/newfifo/ll8_shortfifo.v b/usrp2/fpga/control_lib/newfifo/ll8_shortfifo.v new file mode 100644 index 000000000..39ada9a4f --- /dev/null +++ b/usrp2/fpga/control_lib/newfifo/ll8_shortfifo.v @@ -0,0 +1,13 @@ + + +module ll8_shortfifo + (input clk, input reset, input clear, + input [7:0] datain, input sof_i, input eof_i, input error_i, input src_rdy_i, output dst_rdy_o, + output [7:0] dataout, output sof_o, output eof_o, output error_o, output src_rdy_o, input dst_rdy_i); + + fifo_short #(.WIDTH(11)) fifo_short + (.clk(clk), .reset(reset), .clear(clear), + .datain({error_i,eof_i,sof_i,datain}), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), + .dataout({error_o,eof_o,sof_o,dataout}), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); + +endmodule // ll8_shortfifo diff --git a/usrp2/fpga/control_lib/newfifo/newfifo_2clock.v b/usrp2/fpga/control_lib/newfifo/newfifo_2clock.v new file mode 100644 index 000000000..23a6f693c --- /dev/null +++ b/usrp2/fpga/control_lib/newfifo/newfifo_2clock.v @@ -0,0 +1,82 @@ + +module newfifo_2clock + #(parameter DWIDTH=32, AWIDTH=9) + (input wclk, input [DWIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, output reg [AWIDTH-1:0] level_wclk, + input rclk, output [DWIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, output reg [AWIDTH-1:0] level_rclk, + input arst); + + wire full, empty, write, read; + + assign dst_rdy_o = ~full; + assign src_rdy_o = ~empty; + assign write = src_rdy_i & dst_rdy_o; + assign read = src_rdy_o & dst_rdy_i; + +//`define USE_XLNX_FIFO 1 +`ifdef USE_XLNX_FIFO + fifo_xlnx_512x36_2clk mac_tx_fifo_2clk + (.rst(rst), + .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(fifo_occupied[8:0]), + .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count() ); +`else + // ISE sucks, so the following doesn't work properly + + reg [AWIDTH-1:0] wr_addr, rd_addr; + wire [AWIDTH-1:0] wr_addr_rclk, rd_addr_wclk; + wire [AWIDTH-1:0] next_rd_addr; + wire enb_read; + + // Write side management + wire [AWIDTH-1:0] next_wr_addr = wr_addr + 1; + always @(posedge wclk or posedge arst) + if(arst) + wr_addr <= 0; + else if(write) + wr_addr <= next_wr_addr; + assign full = (next_wr_addr == rd_addr_wclk); + + // RAM for data storage. Data out is registered, complicating the + // read side logic + ram_2port #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) mac_rx_ff_ram + (.clka(wclk),.ena(1'b1),.wea(write),.addra(wr_addr),.dia(datain),.doa(), + .clkb(rclk),.enb(enb_read),.web(1'b0),.addrb(next_rd_addr),.dib(0),.dob(dataout) ); + + // Read side management + reg data_valid; + assign empty = ~data_valid; + assign next_rd_addr = rd_addr + data_valid; + assign enb_read = read | ~data_valid; + + always @(posedge rclk or posedge arst) + if(arst) + rd_addr <= 0; + else if(read) + rd_addr <= rd_addr + 1; + + always @(posedge rclk or posedge arst) + if(arst) + data_valid <= 0; + else + if(read & (next_rd_addr == wr_addr_rclk)) + data_valid <= 0; + else if(next_rd_addr != wr_addr_rclk) + data_valid <= 1; + + // Send pointers across clock domains via gray code + gray_send #(.WIDTH(AWIDTH)) send_wr_addr + (.clk_in(wclk),.addr_in(wr_addr), + .clk_out(rclk),.addr_out(wr_addr_rclk) ); + + gray_send #(.WIDTH(AWIDTH)) send_rd_addr + (.clk_in(rclk),.addr_in(rd_addr), + .clk_out(wclk),.addr_out(rd_addr_wclk) ); + + // Generate fullness info, these are approximate and may be delayed + // and are only for higher-level flow control. + // Only full and empty are guaranteed exact. + always @(posedge wclk) + level_wclk <= wr_addr - rd_addr_wclk; + always @(posedge rclk) + level_rclk <= wr_addr_rclk - rd_addr; +`endif +endmodule // fifo_2clock diff --git a/usrp2/fpga/models/adc_model.v b/usrp2/fpga/models/adc_model.v index 247472c35..e5a3ee0d8 100644 --- a/usrp2/fpga/models/adc_model.v +++ b/usrp2/fpga/models/adc_model.v @@ -22,10 +22,9 @@ module adc_model assign adc_ovf_b = adc_oe_b ? 1'b0 : 1'bz; real phase = 0; - real sample_rate = 100000000; - real freq = 330000/sample_rate; // 330 kHz + real freq = 330000/100000000; - real scale = math.pow(2,13)-2; + real scale = 8190; // math.pow(2,13)-2; always @(posedge clk) if(rst) begin diff --git a/usrp2/fpga/sdr_lib/rx_control.v b/usrp2/fpga/sdr_lib/rx_control.v index d41a28bcf..ae821e822 100644 --- a/usrp2/fpga/sdr_lib/rx_control.v +++ b/usrp2/fpga/sdr_lib/rx_control.v @@ -9,15 +9,12 @@ module rx_control input [31:0] master_time, output overrun, - // To Buffer interface + // To FIFO interface of Buffer Pool output [31:0] wr_dat_o, - output wr_write_o, - output wr_done_o, - output wr_error_o, - + output [3:0] wr_flags_o, input wr_ready_i, - input wr_full_i, - + output wr_ready_o, + // From DSP Core input [31:0] sample, output run, @@ -68,35 +65,10 @@ module rx_control // Buffer interface to internal FIFO wire write, full, read, empty; wire sop_o, eop_o; - - reg xfer_state; - localparam XFER_IDLE = 1'b0; - localparam XFER_GO = 1'b1; - - always @(posedge clk) - if(rst) - xfer_state <= XFER_IDLE; - else - if(clear_overrun) - xfer_state <= XFER_IDLE; - else - case(xfer_state) - XFER_IDLE : - if(wr_ready_i) - xfer_state <= XFER_GO; - XFER_GO : - if((eop_o | wr_full_i) & wr_write_o) - xfer_state <= XFER_IDLE; - default : - xfer_state <= XFER_IDLE; - endcase // case(xfer_state) + assign wr_flags_o = {2'b00, eop_o, sop_o}; + assign wr_ready_o = ~empty; + assign read = wr_ready_i & wr_ready_o; - assign wr_write_o = (xfer_state == XFER_GO) & ~empty; - assign wr_done_o = (eop_o & wr_write_o); - assign wr_error_o = 0; // FIXME add check here for eop if we have wr_full_i once we have IBS - - assign read = wr_write_o | (~empty & ~sop_o); // FIXME what if there is junk between packets? - wire [33:0] fifo_line; // Internal FIFO, size 9 is 2K, size 10 is 4K @@ -206,8 +178,8 @@ module rx_control ((ibs_state == IBS_RUNNING) & strobe & ~full & (lines_left==1) & chain) ) & ~empty_ctrl; - assign debug_rx = { 6'd0,send_imm,chain, - wr_write_o, wr_done_o, wr_ready_i, wr_full_i,xfer_state,eop_o, sop_o, run, + assign debug_rx = { 8'd0, + 1'd0, send_imm, chain, wr_ready_i,wr_ready_o, eop_o, sop_o, run, write,full,read,empty,write_ctrl,full_ctrl,read_ctrl,empty_ctrl, sc_pre1, clear_overrun, go_now, too_late, overrun, ibs_state[2:0] }; endmodule // rx_control diff --git a/usrp2/fpga/sdr_lib/tx_control.v b/usrp2/fpga/sdr_lib/tx_control.v index 0c4ab1a52..8766afd8b 100644 --- a/usrp2/fpga/sdr_lib/tx_control.v +++ b/usrp2/fpga/sdr_lib/tx_control.v @@ -9,13 +9,11 @@ module tx_control input [31:0] master_time, output underrun, - // To Buffer interface + // To FIFO interface from Buffer Pool input [31:0] rd_dat_i, - input rd_sop_i, - input rd_eop_i, - output rd_read_o, - output rd_done_o, - output rd_error_o, + input [3:0] rd_flags_i, + input rd_ready_i, + output rd_ready_o, // To DSP Core output [31:0] sample, @@ -31,6 +29,10 @@ module tx_control output [31:0] debug ); + wire rd_sop_i = rd_flags_i[0]; // Unused + wire rd_eop_i = rd_flags_i[1]; + wire rd_occ_i = rd_flags_i[3:2]; // Unused, should always be 0 + // Buffer interface to internal FIFO wire write_data, write_ctrl, full_data, full_ctrl; wire read_data, read_ctrl, empty_data, empty_ctrl; @@ -39,57 +41,51 @@ module tx_control reg [2:0] held_flags; localparam XFER_IDLE = 0; - localparam XFER_1 = 1; - localparam XFER_2 = 2; - localparam XFER_DATA = 3; + localparam XFER_CTRL = 1; + localparam XFER_PKT = 2; + // Add underrun state? always @(posedge clk) if(rst) xfer_state <= XFER_IDLE; + else if(clear_state) + xfer_state <= XFER_IDLE; else - if(clear_state) - xfer_state <= XFER_IDLE; - else + if(rd_ready_i & rd_ready_o) case(xfer_state) XFER_IDLE : - if(rd_sop_i) - xfer_state <= XFER_1; - XFER_1 : begin - xfer_state <= XFER_2; + xfer_state <= XFER_CTRL; held_flags <= rd_dat_i[2:0]; end - XFER_2 : - if(~full_ctrl) - xfer_state <= XFER_DATA; - XFER_DATA : - if(rd_eop_i & ~full_data) + XFER_CTRL : + xfer_state <= XFER_PKT; + XFER_PKT : + if(rd_eop_i) xfer_state <= XFER_IDLE; endcase // case(xfer_state) - assign write_data = (xfer_state == XFER_DATA) & ~full_data; - assign write_ctrl = (xfer_state == XFER_2) & ~full_ctrl; + assign write_data = (xfer_state == XFER_PKT) & rd_ready_i & rd_ready_o; + assign write_ctrl = (xfer_state == XFER_CTRL) & rd_ready_i & rd_ready_o; - assign rd_read_o = (xfer_state == XFER_1) | write_data | write_ctrl; - assign rd_done_o = 0; // Always take everything we're given - assign rd_error_o = 0; // Should we indicate overruns here? + assign rd_ready_o = ~full_data & ~full_ctrl; wire [31:0] data_o; - wire sop_o, eop_o, eob, sob, send_imm; + wire eop_o, eob, sob, send_imm; wire [31:0] sendtime; wire [4:0] occ_ctrl; - cascadefifo2 #(.WIDTH(34),.SIZE(FIFOSIZE)) txctrlfifo + cascadefifo2 #(.WIDTH(33),.SIZE(FIFOSIZE)) txctrlfifo (.clk(clk),.rst(rst),.clear(clear_state), - .datain({rd_sop_i,rd_eop_i,rd_dat_i}), .write(write_data), .full(full_data), - .dataout({sop_o,eop_o,data_o}), .read(read_data), .empty(empty_data), + .datain({rd_eop_i,rd_dat_i[31:0]}), .write(write_data), .full(full_data), + .dataout({eop_o,data_o}), .read(read_data), .empty(empty_data), .space(), .occupied(fifo_occupied) ); assign fifo_full = full_data; assign fifo_empty = empty_data; shortfifo #(.WIDTH(35)) ctrlfifo (.clk(clk),.rst(rst),.clear(clear_state), - .datain({held_flags[2:0],rd_dat_i}), .write(write_ctrl), .full(full_ctrl), + .datain({held_flags[2:0],rd_dat_i[31:0]}), .write(write_ctrl), .full(full_ctrl), .dataout({send_imm,sob,eob,sendtime}), .read(read_ctrl), .empty(empty_ctrl), .space(), .occupied(occ_ctrl) ); diff --git a/usrp2/fpga/serdes/serdes.v b/usrp2/fpga/serdes/serdes.v index 8429b8fd9..17049bfe6 100644 --- a/usrp2/fpga/serdes/serdes.v +++ b/usrp2/fpga/serdes/serdes.v @@ -7,12 +7,10 @@ module serdes (input clk, input rst, // TX side output ser_tx_clk, output [15:0] ser_t, output ser_tklsb, output ser_tkmsb, - input [31:0] rd_dat_i, output rd_read_o, output rd_done_o, output rd_error_o, - input rd_sop_i, input rd_eop_i, + input [31:0] rd_dat_i, input [3:0] rd_flags_i, output rd_ready_o, input rd_ready_i, // RX side input ser_rx_clk, input [15:0] ser_r, input ser_rklsb, input ser_rkmsb, - output [31:0] wr_dat_o, output wr_write_o, output wr_done_o, output wr_error_o, - input wr_ready_i, input wr_full_i, + output [31:0] wr_dat_o, output [3:0] wr_flags_o, output wr_ready_o, input wr_ready_i, output [15:0] tx_occupied, output tx_full, output tx_empty, output [15:0] rx_occupied, output rx_full, output rx_empty, @@ -29,8 +27,7 @@ module serdes serdes_tx #(.FIFOSIZE(TXFIFOSIZE)) serdes_tx (.clk(clk),.rst(rst), .ser_tx_clk(ser_tx_clk),.ser_t(ser_t),.ser_tklsb(ser_tklsb),.ser_tkmsb(ser_tkmsb), - .rd_dat_i(rd_dat_i),.rd_read_o(rd_read_o),.rd_done_o(rd_done_o),.rd_error_o(rd_error_o), - .rd_sop_i(rd_sop_i),.rd_eop_i(rd_eop_i), + .rd_dat_i(rd_dat_i),.rd_flags_i(rd_flags_i),.rd_ready_o(rd_ready_o),.rd_ready_i(rd_ready_i), .inhibit_tx(inhibit_tx), .send_xon(send_xon), .send_xoff(send_xoff), .sent(sent), .fifo_occupied(tx_occupied),.fifo_full(tx_full),.fifo_empty(tx_empty), .debug(debug_tx) ); @@ -38,8 +35,7 @@ module serdes serdes_rx #(.FIFOSIZE(RXFIFOSIZE)) serdes_rx (.clk(clk),.rst(rst), .ser_rx_clk(ser_rx_clk),.ser_r(ser_r),.ser_rklsb(ser_rklsb),.ser_rkmsb(ser_rkmsb), - .wr_dat_o(wr_dat_o),.wr_write_o(wr_write_o),.wr_done_o(wr_done_o),.wr_error_o(wr_error_o), - .wr_ready_i(wr_ready_i),.wr_full_i(wr_full_i), + .wr_dat_o(wr_dat_o),.wr_flags_o(wr_flags_o),.wr_ready_o(wr_ready_o),.wr_ready_i(wr_ready_i), .fifo_space(fifo_space), .xon_rcvd(xon_rcvd), .xoff_rcvd(xoff_rcvd), .fifo_occupied(rx_occupied),.fifo_full(rx_full),.fifo_empty(rx_empty), .serdes_link_up(serdes_link_up), .debug(debug_rx) ); @@ -55,13 +51,13 @@ module serdes //assign debug = { fifo_space, send_xon, send_xoff, debug_rx[13:0] }; //assign debug = debug_rx; - assign debug0 = { { debug_tx[3:0] /* xfer_active,state[2:0] */, rd_read_o, rd_done_o, rd_sop_i, rd_eop_i }, + assign debug0 = { { 2'b00, rd_ready_o, rd_ready_i, rd_flags_i[3:0]}, { debug_tx[5:4] /* full,empty */ , inhibit_tx, send_xon, send_xoff, sent, ser_tkmsb, ser_tklsb}, { ser_t[15:8] }, { ser_t[7:0] } }; assign debug1 = { { debug_rx[7:0] }, /* odd,xfer_active,sop_i,eop_i,error_i,state[2:0] */ - { wr_write_o, wr_error_o, wr_ready_i, wr_done_o, xon_rcvd, xoff_rcvd, ser_rkmsb, ser_rklsb }, + { wr_flags_o[1:0], wr_ready_i, wr_ready_o, xon_rcvd, xoff_rcvd, ser_rkmsb, ser_rklsb }, { ser_r[15:8] }, { ser_r[7:0] } }; endmodule // serdes diff --git a/usrp2/fpga/serdes/serdes_rx.v b/usrp2/fpga/serdes/serdes_rx.v index 8c488d7d7..aaca94ff1 100644 --- a/usrp2/fpga/serdes/serdes_rx.v +++ b/usrp2/fpga/serdes/serdes_rx.v @@ -32,12 +32,10 @@ module serdes_rx input ser_rkmsb, output [31:0] wr_dat_o, - output wr_write_o, - output wr_done_o, - output wr_error_o, + output [3:0] wr_flags_o, input wr_ready_i, - input wr_full_i, - + output wr_ready_o, + output [15:0] fifo_space, output xon_rcvd, output xoff_rcvd, @@ -83,6 +81,7 @@ module serdes_rx wire [15:0] nextCRC; reg write_d; + wire rst_rxclk; oneshot_2clk rst_1s(.clk_in(clk),.in(rst),.clk_out(ser_rx_clk),.out(rst_rxclk)); /* @@ -311,34 +310,21 @@ module serdes_rx .wr_data_count() ); assign fifo_space = {{(16-FIFOSIZE){1'b0}},{FIFOSIZE{1'b1}}} - {{(16-FIFOSIZE){1'b0}},level}; - assign fifo_occupied = { {(16-FIFOSIZE){1'b0}}, level }; - assign fifo_full = full; // Note -- fifo_full is in the wrong clock domain - assign fifo_empty = empty; + assign fifo_occupied = { {(16-FIFOSIZE){1'b0}}, level }; + assign fifo_full = full; // Note -- fifo_full is in the wrong clock domain + assign fifo_empty = empty; `endif // `ifdef XILFIFO // Internal FIFO to Buffer interface - reg xfer_active; - - always @(posedge clk) - if(rst) - xfer_active <= 0; - else if(xfer_active & ~empty & (eop_o | wr_full_i | error_o)) - xfer_active <= 0; - else if(wr_ready_i & sop_o) - xfer_active <= 1; - - assign read = (xfer_active | ~sop_o) & ~empty; - - assign wr_write_o = xfer_active & ~empty; - assign wr_done_o = eop_o & ~empty & xfer_active; - //assign wr_error_o = xfer_active & ((wr_full_i & ~eop_o & ~empty)|error_o); - assign wr_error_o = xfer_active & ~empty & error_o; - - assign wr_dat_o = line_o; - - wire slu = ~(({2'b11,K_ERROR,K_ERROR}=={ser_rkmsb,ser_rklsb,ser_r}) || + assign read = wr_ready_i & wr_ready_o; + assign wr_ready_o = ~empty; + assign wr_dat_o = line_o; + assign wr_flags_o = { 2'b00, eop_o | error_o, sop_o | error_o }; + + wire slu = ~(({2'b11,K_ERROR,K_ERROR}=={ser_rkmsb,ser_rklsb,ser_r}) || ({2'b11,K_LOS,K_LOS}=={ser_rkmsb,ser_rklsb,ser_r})); + reg [3:0] slu_reg; always @(posedge clk) @@ -348,6 +334,6 @@ module serdes_rx always @(posedge clk) serdes_link_up <= &slu_reg[3:1]; - assign debug = { full, empty, odd, xfer_active, sop_i, eop_i, error_i, state[2:0] }; + assign debug = { full, empty, odd, sop_i, eop_i, error_i, state[2:0] }; endmodule // serdes_rx diff --git a/usrp2/fpga/serdes/serdes_tx.v b/usrp2/fpga/serdes/serdes_tx.v index fa4abe5df..b6f19370e 100644 --- a/usrp2/fpga/serdes/serdes_tx.v +++ b/usrp2/fpga/serdes/serdes_tx.v @@ -33,11 +33,9 @@ module serdes_tx // TX Stream Interface input [31:0] rd_dat_i, - output rd_read_o, - output rd_done_o, - output rd_error_o, - input rd_sop_i, - input rd_eop_i, + input [3:0] rd_flags_i, + output rd_ready_o, + input rd_ready_i, // Flow control interface input inhibit_tx, @@ -82,33 +80,24 @@ module serdes_tx wire sop_o, eop_o, write, full, read, empty; wire [31:0] data_o; reg xfer_active; + + wire rd_sop_i = rd_flags_i[0]; + wire rd_eop_i = rd_flags_i[1]; + wire [1:0] rd_occ_i = rd_flags_i[3:2]; // Unused cascadefifo2 #(.WIDTH(34),.SIZE(FIFOSIZE)) serdes_tx_fifo (.clk(clk),.rst(rst),.clear(0), .datain({rd_sop_i,rd_eop_i,rd_dat_i}), .write(write), .full(full), .dataout({sop_o,eop_o,data_o}), .read(read), .empty(empty), .space(), .occupied(fifo_occupied) ); - assign fifo_full = full; - assign fifo_empty = empty; - - // Buffer interface to internal FIFO - always @(posedge clk) - if(rst) - xfer_active <= 0; - else if(rd_eop_i & ~full) // In case we can't store last line right away - xfer_active <= 0; - else if(rd_sop_i) - xfer_active <= 1; - - assign write = xfer_active & ~full; - - assign rd_read_o = write; - assign rd_done_o = 0; // Always take everything we're given - assign rd_error_o = 0; // No chance for errors anticipated - - - // FIXME Implement flow control + assign fifo_full = full; + assign fifo_empty = empty; + + assign write = rd_ready_i & rd_ready_o; + assign rd_ready_o = ~full; + + // FIXME Implement flow control reg [15:0] second_word; reg [33:0] pipeline; diff --git a/usrp2/fpga/simple_gemac/delay_line.v b/usrp2/fpga/simple_gemac/delay_line.v index 3d76c4928..d371bb9c5 100644 --- a/usrp2/fpga/simple_gemac/delay_line.v +++ b/usrp2/fpga/simple_gemac/delay_line.v @@ -7,7 +7,7 @@ module delay_line input [WIDTH-1:0] din, output [WIDTH-1:0] dout); - integer i; + genvar i; generate for (i=0;i<WIDTH;i=i+1) begin : gen_delay diff --git a/usrp2/fpga/simple_gemac/eth_tasks_f36.v b/usrp2/fpga/simple_gemac/eth_tasks_f36.v new file mode 100644 index 000000000..b7fa52c07 --- /dev/null +++ b/usrp2/fpga/simple_gemac/eth_tasks_f36.v @@ -0,0 +1,89 @@ + + +task SendFlowCtrl; + input [15:0] fc_len; + begin + $display("Sending Flow Control, quanta = %d, time = %d", fc_len,$time); + pause_time <= fc_len; + @(posedge clk); + pause_req <= 1; + @(posedge clk); + pause_req <= 0; + $display("Sent Flow Control"); + end +endtask // SendFlowCtrl + +task SendPacket_to_fifo36; + input [31:0] data_start; + input [15:0] data_len; + reg [15:0] count; + begin + $display("Sending Packet Len=%d, %d", data_len, $time); + count <= 2; + tx_f36_dat <= {2'b0, 1'b0, 1'b1, data_start}; + tx_f36_src_rdy <= 1; + #1; + while(count < data_len) + begin + while(~tx_f36_dst_rdy) + @(posedge clk); + @(posedge clk); + tx_f36_dat[31:0] = tx_f36_dat[31:0] + 32'h0101_0101; + count = count + 4; + tx_f36_dat[32] <= 0; + end + tx_f36_dat[3] <= 1; + while(~tx_f36_dst_rdy) + @(posedge clk); + @(posedge clk); + tx_f36_src_rdy <= 0; + end +endtask // SendPacket_to_fifo36 + + +task Waiter; + input [31:0] wait_length; + begin + tx_ll_src_rdy2 <= 0; + repeat(wait_length) + @(posedge clk); + tx_ll_src_rdy2 <= 1; + end +endtask // Waiter + +task SendPacketFromFile_f36; + input [31:0] data_len; + input [31:0] wait_length; + input [31:0] wait_time; + + integer count; + begin + $display("Sending Packet From File to LL8 Len=%d, %d",data_len,$time); + $readmemh("test_packet.mem",pkt_rom ); + + while(~tx_f36_dst_rdy) + @(posedge clk); + tx_f36_data2 <= pkt_rom[0]; + tx_f36_src_rdy <= 1; + tx_ll_eof2 <= 0; + @(posedge clk); + + for(i=1;i<data_len-1;i=i+1) + begin + while(~tx_ll_dst_rdy2) + @(posedge clk); + tx_ll_data2 <= pkt_rom[i]; + tx_ll_sof2 <= 0; + @(posedge clk); + if(i==wait_time) + Waiter(wait_length); + end + + while(~tx_ll_dst_rdy2) + @(posedge clk); + tx_ll_eof2 <= 1; + tx_ll_data2 <= pkt_rom[data_len-1]; + @(posedge clk); + tx_ll_src_rdy2 <= 0; + end +endtask diff --git a/usrp2/fpga/simple_gemac/ll8_shortfifo.v b/usrp2/fpga/simple_gemac/ll8_shortfifo.v index 39ada9a4f..e69de29bb 100644 --- a/usrp2/fpga/simple_gemac/ll8_shortfifo.v +++ b/usrp2/fpga/simple_gemac/ll8_shortfifo.v @@ -1,13 +0,0 @@ - - -module ll8_shortfifo - (input clk, input reset, input clear, - input [7:0] datain, input sof_i, input eof_i, input error_i, input src_rdy_i, output dst_rdy_o, - output [7:0] dataout, output sof_o, output eof_o, output error_o, output src_rdy_o, input dst_rdy_i); - - fifo_short #(.WIDTH(11)) fifo_short - (.clk(clk), .reset(reset), .clear(clear), - .datain({error_i,eof_i,sof_i,datain}), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), - .dataout({error_o,eof_o,sof_o,dataout}), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); - -endmodule // ll8_shortfifo diff --git a/usrp2/fpga/simple_gemac/rxmac_to_ll8.v b/usrp2/fpga/simple_gemac/rxmac_to_ll8.v index d4015716e..5ec233d95 100644 --- a/usrp2/fpga/simple_gemac/rxmac_to_ll8.v +++ b/usrp2/fpga/simple_gemac/rxmac_to_ll8.v @@ -6,6 +6,13 @@ module rxmac_to_ll8 reg [2:0] xfer_state; + localparam XFER_IDLE = 0; + localparam XFER_ACTIVE = 1; + localparam XFER_ERROR = 2; + localparam XFER_ERROR2 = 3; + localparam XFER_OVERRUN = 4; + localparam XFER_OVERRUN2 = 5; + assign ll_data = rx_data; assign ll_src_rdy = ((rx_valid & (xfer_state != XFER_OVERRUN2) ) | (xfer_state == XFER_ERROR) @@ -14,13 +21,6 @@ module rxmac_to_ll8 assign ll_eof = (rx_ack | (xfer_state==XFER_ERROR) | (xfer_state==XFER_OVERRUN)); assign ll_error = (xfer_state == XFER_ERROR)|(xfer_state==XFER_OVERRUN); - localparam XFER_IDLE = 0; - localparam XFER_ACTIVE = 1; - localparam XFER_ERROR = 2; - localparam XFER_ERROR2 = 3; - localparam XFER_OVERRUN = 4; - localparam XFER_OVERRUN2 = 5; - always @(posedge clk) if(reset | clear) xfer_state <= XFER_IDLE; diff --git a/usrp2/fpga/simple_gemac/simple_gemac_rx.v b/usrp2/fpga/simple_gemac/simple_gemac_rx.v index 7daa9adad..c50791ff0 100644 --- a/usrp2/fpga/simple_gemac/simple_gemac_rx.v +++ b/usrp2/fpga/simple_gemac/simple_gemac_rx.v @@ -8,7 +8,24 @@ module simple_gemac_rx input pass_ucast, input pass_mcast, input pass_bcast, input pass_pause, input pass_all, output reg [15:0] pause_quanta_rcvd, output pause_rcvd ); - reg [7:0] rxd_d1; + localparam RX_IDLE = 0; + localparam RX_PREAMBLE = 1; + localparam RX_FRAME = 2; + localparam RX_GOODFRAME = 3; + localparam RX_DO_PAUSE = 4; + localparam RX_ERROR = 5; + localparam RX_DROP = 6; + + localparam RX_PAUSE = 16; + localparam RX_PAUSE_CHK88 = RX_PAUSE + 5; + localparam RX_PAUSE_CHK08 = RX_PAUSE_CHK88 + 1; + localparam RX_PAUSE_CHK00 = RX_PAUSE_CHK08 + 1; + localparam RX_PAUSE_CHK01 = RX_PAUSE_CHK00 + 1; + localparam RX_PAUSE_STORE_MSB = RX_PAUSE_CHK01 + 1; + localparam RX_PAUSE_STORE_LSB = RX_PAUSE_STORE_MSB + 1; + localparam RX_PAUSE_WAIT_CRC = RX_PAUSE_STORE_LSB + 1; + + reg [7:0] rxd_d1; reg rx_dv_d1, rx_er_d1; assign rx_clk = GMII_RX_CLK; @@ -19,10 +36,15 @@ module simple_gemac_rx rxd_d1 <= GMII_RXD; end + reg [7:0] rx_state; wire [7:0] rxd_del; wire rx_dv_del, rx_er_del; reg go_filt; + wire match_crc; + wire clear_crc = rx_state == RX_IDLE; + wire calc_crc = (rx_state == RX_FRAME) | rx_state[7:4]==4'h1; + localparam DELAY = 6; delay_line #(.WIDTH(10)) rx_delay (.clk(rx_clk), .delay(DELAY), .din({rx_dv_d1,rx_er_d1,rxd_d1}),.dout({rx_dv_del,rx_er_dl,rxd_del})); @@ -37,7 +59,6 @@ module simple_gemac_rx wire keep_packet = (pass_ucast & is_ucast) | (pass_mcast & is_mcast) | (pass_bcast & is_bcast) | (pass_pause & is_pause) | pass_all; - reg [7:0] rx_state; assign rx_data = rxd_del; assign rx_error = (rx_state == RX_ERROR); @@ -58,24 +79,6 @@ module simple_gemac_rx address_filter af_pause (.clk(rx_clk), .reset(reset), .go(go_filt), .data(rxd_d1), .address(48'h0180_c200_0001), .match(is_pause), .done()); - localparam RX_IDLE = 0; - localparam RX_PREAMBLE = 1; - localparam RX_FRAME = 2; - localparam RX_GOODFRAME = 3; - localparam RX_DO_PAUSE = 4; - localparam RX_ERROR = 5; - localparam RX_DROP = 6; - - localparam RX_PAUSE = 16; - localparam RX_PAUSE_CHK88 = RX_PAUSE + 5; - localparam RX_PAUSE_CHK08 = RX_PAUSE_CHK88 + 1; - localparam RX_PAUSE_CHK00 = RX_PAUSE_CHK08 + 1; - localparam RX_PAUSE_CHK01 = RX_PAUSE_CHK00 + 1; - localparam RX_PAUSE_STORE_MSB = RX_PAUSE_CHK01 + 1; - localparam RX_PAUSE_STORE_LSB = RX_PAUSE_STORE_MSB + 1; - localparam RX_PAUSE_WAIT_CRC = RX_PAUSE_STORE_LSB + 1; - - always @(posedge rx_clk) go_filt <= (rx_state==RX_PREAMBLE) & (rxd_d1 == 8'hD5); @@ -155,9 +158,6 @@ module simple_gemac_rx endcase // case (rx_state) assign pause_rcvd = (rx_state == RX_DO_PAUSE); - wire match_crc; - wire clear_crc = rx_state == RX_IDLE; - wire calc_crc = (rx_state == RX_FRAME) | rx_state[7:4]==4'h1; crc crc_check(.clk(rx_clk),.reset(reset),.clear(clear_crc), .data(rxd_d1),.calc(calc_crc),.crc_out(),.match(match_crc)); diff --git a/usrp2/fpga/simple_gemac/simple_gemac_tx.v b/usrp2/fpga/simple_gemac/simple_gemac_tx.v index 690fd5c37..dd870d04d 100644 --- a/usrp2/fpga/simple_gemac/simple_gemac_tx.v +++ b/usrp2/fpga/simple_gemac/simple_gemac_tx.v @@ -23,14 +23,6 @@ module simple_gemac_tx wire [31:0] crc_out; - localparam MIN_FRAME_LEN = 64 + 8 - 4; // Min frame length includes preamble but not CRC - localparam MAX_FRAME_LEN = 8192; // How big are the jumbo frames we want to handle? - always @(posedge tx_clk) - if(reset |(tx_state == TX_IDLE)) - frame_len_ctr <= 0; - else - frame_len_ctr <= frame_len_ctr + 1; - localparam TX_IDLE = 0; localparam TX_PREAMBLE = 1; localparam TX_SOF_DEL = TX_PREAMBLE + 7; @@ -48,6 +40,14 @@ module simple_gemac_tx localparam TX_PAUSE_FIRST = TX_PAUSE_SOF + 1; localparam TX_PAUSE_END = TX_PAUSE_SOF + 18; + localparam MIN_FRAME_LEN = 64 + 8 - 4; // Min frame length includes preamble but not CRC + localparam MAX_FRAME_LEN = 8192; // How big are the jumbo frames we want to handle? + always @(posedge tx_clk) + if(reset |(tx_state == TX_IDLE)) + frame_len_ctr <= 0; + else + frame_len_ctr <= frame_len_ctr + 1; + reg send_pause; reg [15:0] pause_time_held; diff --git a/usrp2/fpga/simple_gemac/simple_gemac_wrapper.v b/usrp2/fpga/simple_gemac/simple_gemac_wrapper.v index cd586ae5d..e21eafb80 100644 --- a/usrp2/fpga/simple_gemac/simple_gemac_wrapper.v +++ b/usrp2/fpga/simple_gemac/simple_gemac_wrapper.v @@ -8,13 +8,10 @@ module simple_gemac_wrapper // Flow Control Interface input pause_req, input [15:0] pause_time, - // RX Client Interface - output rx_clk, output [7:0] rx_ll_data, output rx_ll_sof, output rx_ll_eof, - output rx_ll_error, output rx_ll_src_rdy, input rx_ll_dst_rdy, - - // TX Client Interface - output tx_clk, input [7:0] tx_ll_data, input tx_ll_sof, input tx_ll_eof, - input tx_ll_src_rdy, output tx_ll_dst_rdy, + // Client FIFO Interfaces + input sys_clk, + output [35:0] rx_f36_data, output rx_f36_src_rdy, input rx_f36_dst_rdy, + input [35:0] tx_f36_data, input tx_f36_src_rdy, output tx_f36_dst_rdy, // Wishbone Interface input wb_clk, input wb_rst, input wb_stb, input wb_cyc, output wb_ack, input wb_we, @@ -59,14 +56,66 @@ module simple_gemac_wrapper .pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast), .pass_pause(pass_pause), .pass_all(pass_all), .pause_en(pause_en) ); + // RX FIFO Chain + wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy; + wire rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2_n, rx_ll_dst_rdy2; + wire [7:0] rx_ll_data, rx_ll_data2; + wire [35:0] rx_f36_data_int1; + wire rx_f36_src_rdy_int1, rx_f36_dst_rdy_int1; + rxmac_to_ll8 rx_adapt (.clk(rx_clk), .reset(rx_reset), .clear(0), .rx_data(rx_data), .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack), .ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(rx_ll_error), .ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy)); + + ll8_shortfifo rx_sfifo + (.clk(rx_clk), .reset(rx_reset), .clear(0), + .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof), + .error_i(rx_ll_error), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy), + .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2), + .error_o(rx_ll_error2), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(~rx_ll_dst_rdy2_n)); + + ll8_to_fifo36 ll8_to_fifo36 + (.clk(rx_clk), .reset(rx_reset), .clear(0), + .ll_data(rx_ll_data2), .ll_sof_n(~rx_ll_sof2), .ll_eof_n(~rx_ll_eof2), + .ll_src_rdy_n(~rx_ll_src_rdy2), .ll_dst_rdy_n(rx_ll_dst_rdy2_n), + .f36_data(rx_f36_data_int1), .f36_src_rdy_o(rx_f36_src_rdy_int1), .f36_dst_rdy_i(rx_f36_dst_rdy_int1)); + + cascadefifo_2clock #(.DWIDTH(36), .AWIDTH(9)) rx_2clk_fifo + (.wclk(rx_clk), .datain(rx_f36_data_int1), + .src_rdy_i(rx_f36_src_rdy_int1), .dst_rdy_o(rx_f36_dst_rdy_int1), .level_wclk(), + .rclk(sys_clk), .dataout(rx_f36_data), + .src_rdy_o(rx_f36_src_rdy), .dst_rdy_i(rx_f36_dst_rdy), .level_rclk(), .arst(reset)); + + // TX FIFO Chain + wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy; + wire tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2; + wire [7:0] tx_ll_data, tx_ll_data2; + wire [35:0] tx_f36_data_int1; + wire tx_f36_src_rdy_int1, tx_f36_dst_rdy_int1; + + cascadefifo_2clock #(.DWIDTH(36), .AWIDTH(9)) tx_2clk_fifo + (.wclk(sys_clk), .datain(tx_f36_data), + .src_rdy_i(tx_f36_src_rdy), .dst_rdy_o(tx_f36_dst_rdy), .level_wclk(), + .rclk(tx_clk), .dataout(tx_f36_data_int1), + .src_rdy_o(tx_f36_src_rdy_int1), .dst_rdy_i(tx_f36_dst_rdy_int1), .level_rclk(), .arst(reset)); + + fifo36_to_ll8 fifo36_to_ll8 + (.clk(tx_clk), .reset(tx_reset), .clear(clear), + .f36_data(tx_f36_data_int1), .f36_src_rdy_i(tx_f36_src_rdy_int1), .f36_dst_rdy_o(tx_f36_dst_rdy_int1), + .ll_data(tx_ll_data2), .ll_sof_n(tx_ll_sof2_n), .ll_eof_n(tx_ll_eof2_n), + .ll_src_rdy_n(tx_ll_src_rdy2_n), .ll_dst_rdy_n(~tx_ll_dst_rdy2)); + + ll8_shortfifo tx_sfifo + (.clk(rx_clk), .reset(tx_reset), .clear(clear), + .datain(tx_ll_data2), .sof_i(tx_ll_sof2), .eof_i(tx_ll_eof2), + .error_i(0), .src_rdy_i(~tx_ll_src_rdy2_n), .dst_rdy_o(tx_ll_dst_rdy2), + .dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof), + .error_o(), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy)); ll8_to_txmac ll8_to_txmac - (.clk(tx_clk), .reset(tx_reset), .clear(0), + (.clk(tx_clk), .reset(tx_reset), .clear(clear), .ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof), .ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy), .tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack)); diff --git a/usrp2/fpga/simple_gemac/simple_gemac_wrapper_f36_tb.v b/usrp2/fpga/simple_gemac/simple_gemac_wrapper_f36_tb.v new file mode 100644 index 000000000..804fa8748 --- /dev/null +++ b/usrp2/fpga/simple_gemac/simple_gemac_wrapper_f36_tb.v @@ -0,0 +1,243 @@ + + +module simple_gemac_wrapper_f36_tb; +`include "eth_tasks_f36.v" + + reg clk = 0; + reg reset = 1; + + initial #1000 reset = 0; + always #50 clk = ~clk; + + reg wb_clk = 0; + wire wb_rst = reset; + always #173 wb_clk = ~wb_clk; + + wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK; + wire [7:0] GMII_RXD, GMII_TXD; + + wire rx_valid, rx_error, rx_ack; + wire tx_ack, tx_valid, tx_error; + + wire [7:0] rx_data, tx_data; + + reg [15:0] pause_time; + reg pause_req = 0; + + wire GMII_RX_CLK = GMII_GTX_CLK; + + reg [7:0] FORCE_DAT_ERR = 0; + reg FORCE_ERR = 0; + + // Loopback + assign GMII_RX_DV = GMII_TX_EN; + assign GMII_RX_ER = GMII_TX_ER | FORCE_ERR; + assign GMII_RXD = GMII_TXD ^ FORCE_DAT_ERR; + + + wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy; + wire rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2; + wire rx_ll_dst_rdy2; + wire [7:0] rx_ll_data, rx_ll_data2; + wire rx_ll_error, rx_ll_error2; + + wire [31:0] wb_dat_o; + reg [31:0] wb_dat_i; + reg [7:0] wb_adr; + reg wb_stb=0, wb_cyc=0, wb_we=0; + wire wb_ack; + + reg [35:0] tx_f36_dat; + reg tx_f36_src_rdy; + wire tx_f36_dst_rdy; + + wire [35:0] rx_f36_dat; + wire rx_f36_src_rdy; + reg rx_f36_dst_rdy = 1; + + simple_gemac_wrapper simple_gemac_wrapper + (.clk125(clk), .reset(reset), + .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN), + .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD), + .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV), + .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD), + .pause_req(pause_req), .pause_time(pause_time), + .rx_clk(rx_clk), .rx_ll_data(rx_ll_data), .rx_ll_sof(rx_ll_sof), + .rx_ll_eof(rx_ll_eof), .rx_ll_src_rdy(rx_ll_src_rdy), .rx_ll_dst_rdy(rx_ll_dst_rdy), + .tx_clk(tx_clk), .tx_ll_data(tx_ll_data), .tx_ll_sof(tx_ll_sof), + .tx_ll_eof(tx_ll_eof), .tx_ll_src_rdy(tx_ll_src_rdy), .tx_ll_dst_rdy(tx_ll_dst_rdy), + .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(wb_stb), .wb_cyc(wb_cyc), .wb_ack(wb_ack), + .wb_we(wb_we), .wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o), + .mdio(mdio), .mdc(mdc) ); + + wire rx_ll_dst_rdy2_n; + assign rx_ll_dst_rdy2 = ~rx_ll_dst_rdy2_n; + + ll8_shortfifo rx_sfifo + (.clk(clk), .reset(reset), .clear(0), + .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof), + .error_i(rx_ll_error), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy), + .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2), + .error_o(rx_ll_error2), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(rx_ll_dst_rdy2)); + + ll8_to_fifo36 ll8_to_fifo36 + (.clk(clk), .reset(reset), .clear(0), + .ll_data(rx_ll_data2), .ll_sof_n(~rx_ll_sof2), .ll_eof_n(~rx_ll_eof2), + .ll_src_rdy_n(~rx_ll_src_rdy2), .ll_dst_rdy_n(rx_ll_dst_rdy2_n), + .f36_data(rx_f36_dat), .f36_src_rdy_o(rx_f36_src_rdy), .f36_dst_rdy_i(rx_f36_dst_rdy)); + + wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy; + wire tx_ll_sof2_n, tx_ll_eof2_n; + wire tx_ll_src_rdy2_n, tx_ll_dst_rdy2; + wire [7:0] tx_ll_data, tx_ll_data2; + wire tx_ll_error; + wire tx_ll_error2 = 0; + + fifo36_to_ll8 fifo36_to_ll8 + (.clk(clk), .reset(reset), .clear(clear), + .f36_data(tx_f36_dat), .f36_src_rdy_i(tx_f36_src_rdy), .f36_dst_rdy_o(tx_f36_dst_rdy), + .ll_data(tx_ll_data2), .ll_sof_n(tx_ll_sof2_n), .ll_eof_n(tx_ll_eof2_n), + .ll_src_rdy_n(tx_ll_src_rdy2_n), .ll_dst_rdy_n(~tx_ll_dst_rdy2)); + + ll8_shortfifo tx_sfifo + (.clk(clk), .reset(reset), .clear(clear), + .datain(tx_ll_data2), .sof_i(~tx_ll_sof2_n), .eof_i(~tx_ll_eof2_n), + .error_i(tx_ll_error2), .src_rdy_i(~tx_ll_src_rdy2_n), .dst_rdy_o(tx_ll_dst_rdy2), + .dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof), + .error_o(tx_ll_error), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy)); + + initial $dumpfile("simple_gemac_wrapper_f36_tb.vcd"); + initial $dumpvars(0,simple_gemac_wrapper_f36_tb); + + integer i; + reg [7:0] pkt_rom[0:65535]; + reg [1023:0] ROMFile; + + initial + for (i=0;i<65536;i=i+1) + pkt_rom[i] <= 8'h0; + + initial + begin + @(negedge reset); + repeat (10) + @(posedge clk); + WishboneWR(0,6'b111001); + WishboneWR(4,16'hF1F2); + WishboneWR(8,32'hF3F4_F5F6); + WishboneWR(12,16'h0000); + WishboneWR(16,32'h0000_0000); + + @(posedge clk); + SendFlowCtrl(16'h0007); // Send flow control + @(posedge clk); + #30000; + @(posedge clk); + SendFlowCtrl(16'h0009); // Increase flow control before it expires + #10000; + @(posedge clk); + SendFlowCtrl(16'h0000); // Cancel flow control before it expires + @(posedge clk); + + SendPacket_to_fifo36(8'hAA,10); // This packet gets dropped by the filters + repeat (10) + @(posedge clk); + + SendPacketFromFile_fifo36(60,0,0); // The rest are valid packets + repeat (10) + @(posedge clk); + + SendPacketFromFile_fifo36(61,0,0); + repeat (10) + @(posedge clk); + SendPacketFromFile_fifo36(62,0,0); + repeat (10) + @(posedge clk); + SendPacketFromFile_fifo36(63,0,0); + repeat (1) + @(posedge clk); + SendPacketFromFile_fifo36(64,0,0); + repeat (10) + @(posedge clk); + SendPacketFromFile_fifo36(59,0,0); + repeat (1) + @(posedge clk); + SendPacketFromFile_fifo36(58,0,0); + repeat (1) + @(posedge clk); + SendPacketFromFile_fifo36(100,0,0); + repeat (1) + @(posedge clk); + SendPacketFromFile_fifo36(200,150,30); // waiting 14 empties the fifo, 15 underruns + repeat (1) + @(posedge clk); + SendPacketFromFile_fifo36(100,0,30); + #10000 $finish; + end +/* + // Force a CRC error + initial + begin + #90000; + @(posedge clk); + FORCE_DAT_ERR <= 8'h10; + @(posedge clk); + FORCE_DAT_ERR <= 8'h00; + end + + // Force an RX_ER error (i.e. link loss) + initial + begin + #116000; + @(posedge clk); + FORCE_ERR <= 1; + @(posedge clk); + FORCE_ERR <= 0; + end + + // Cause receive fifo to fill, causing an RX overrun + initial + begin + #126000; + @(posedge clk); + rx_f36_dst_rdy <= 0; + repeat (30) // Repeat of 14 fills the shortfifo, but works. 15 overflows + @(posedge clk); + rx_f36_dst_rdy <= 1; + end + */ + // Tests: Send and recv flow control, send and receive good packets, RX CRC err, RX_ER, RX overrun, TX underrun + // Still need to test: CRC errors on Pause Frames, MDIO, wishbone + + task WishboneWR; + input [7:0] adr; + input [31:0] value; + begin + wb_adr <= adr; + wb_dat_i <= value; + wb_stb <= 1; + wb_cyc <= 1; + wb_we <= 1; + while (~wb_ack) + @(posedge wb_clk); + @(posedge wb_clk); + wb_stb <= 0; + wb_cyc <= 0; + wb_we <= 0; + end + endtask // WishboneWR + + always @(posedge clk) + if(rx_f36_src_rdy & rx_f36_dst_rdy) + begin + if(rx_f36_dat[32] & ~rx_f36_dat[33]) + $display("RX-PKT-START %d",$time); + $display("RX-PKT SOF %d EOF %d ERR %d OCC %d DAT %x",rx_f36_dat[32],rx_f36_dat[33], + &rx_f36_dat[33:32],rx_f36_dat[35:34],rx_f36_dat[31:0]); + if(rx_f36_dat[33] & ~rx_f36_dat[32]) + $display("RX-PKT-END %d",$time); + if(rx_f36_dat[33] & rx_f36_dat[32]) + $display("RX-PKT-ERROR %d",$time); + end + +endmodule // simple_gemac_wrapper_tb diff --git a/usrp2/fpga/testbench/cmdfile b/usrp2/fpga/testbench/cmdfile index 1063f428e..ed251665c 100644 --- a/usrp2/fpga/testbench/cmdfile +++ b/usrp2/fpga/testbench/cmdfile @@ -3,6 +3,7 @@ -y . -y ../top/u2_core -y ../control_lib +-y ../control_lib/newfifo -y ../serdes -y ../sdr_lib -y ../timing diff --git a/usrp2/fpga/top/u2_core/u2_core.v b/usrp2/fpga/top/u2_core/u2_core.v index f12b5af4d..75468a2e8 100755 --- a/usrp2/fpga/top/u2_core/u2_core.v +++ b/usrp2/fpga/top/u2_core/u2_core.v @@ -307,19 +307,21 @@ module u2_core .in(set_data),.out(),.changed(flush_icache)); // Buffer Pool, slave #1 - wire rd0_read, rd0_sop, rd0_error, rd0_done, rd0_eop; - wire rd1_read, rd1_sop, rd1_error, rd1_done, rd1_eop; - wire rd2_read, rd2_sop, rd2_error, rd2_done, rd2_eop; - wire rd3_read, rd3_sop, rd3_error, rd3_done, rd3_eop; + wire rd0_ready_i, rd0_ready_o; + wire rd1_ready_i, rd1_ready_o; + wire rd2_ready_i, rd2_ready_o; + wire rd3_ready_i, rd3_ready_o; + wire [3:0] rd0_flags, rd1_flags, rd2_flags, rd3_flags; wire [31:0] rd0_dat, rd1_dat, rd2_dat, rd3_dat; - wire wr0_write, wr0_done, wr0_error, wr0_ready, wr0_full; - wire wr1_write, wr1_done, wr1_error, wr1_ready, wr1_full; - wire wr2_write, wr2_done, wr2_error, wr2_ready, wr2_full; - wire wr3_write, wr3_done, wr3_error, wr3_ready, wr3_full; + wire wr0_ready_i, wr0_ready_o; + wire wr1_ready_i, wr1_ready_o; + wire wr2_ready_i, wr2_ready_o; + wire wr3_ready_i, wr3_ready_o; + wire [3:0] wr0_flags, wr1_flags, wr2_flags, wr3_flags; wire [31:0] wr0_dat, wr1_dat, wr2_dat, wr3_dat; - buffer_pool buffer_pool + buffer_pool #(.BUF_SIZE(9), .SET_ADDR(64)) buffer_pool (.wb_clk_i(wb_clk),.wb_rst_i(wb_rst), .wb_we_i(s1_we),.wb_stb_i(s1_stb),.wb_adr_i(s1_adr),.wb_dat_i(s1_dat_o), .wb_dat_o(s1_dat_i),.wb_ack_o(s1_ack),.wb_err_o(s1_err),.wb_rty_o(s1_rty), @@ -330,25 +332,17 @@ module u2_core .s0(status_b0),.s1(status_b1),.s2(status_b2),.s3(status_b3), .s4(status_b4),.s5(status_b5),.s6(status_b6),.s7(status_b7), - + // Write Interfaces - .wr0_dat_i(wr0_dat), .wr0_write_i(wr0_write), .wr0_done_i(wr0_done), - .wr0_error_i(wr0_error), .wr0_ready_o(wr0_ready), .wr0_full_o(wr0_full), - .wr1_dat_i(wr1_dat), .wr1_write_i(wr1_write), .wr1_done_i(wr1_done), - .wr1_error_i(wr1_error), .wr1_ready_o(wr1_ready), .wr1_full_o(wr1_full), - .wr2_dat_i(wr2_dat), .wr2_write_i(wr2_write), .wr2_done_i(wr2_done), - .wr2_error_i(wr2_error), .wr2_ready_o(wr2_ready), .wr2_full_o(wr2_full), - .wr3_dat_i(wr3_dat), .wr3_write_i(wr3_write), .wr3_done_i(wr3_done), - .wr3_error_i(wr3_error), .wr3_ready_o(wr3_ready), .wr3_full_o(wr3_full), + .wr0_data_i(wr0_dat), .wr0_flags_i(wr0_flags), .wr0_ready_i(wr0_ready_i), .wr0_ready_o(wr0_ready_o), + .wr1_data_i(wr1_dat), .wr1_flags_i(wr1_flags), .wr1_ready_i(wr1_ready_i), .wr1_ready_o(wr1_ready_o), + .wr2_data_i(wr2_dat), .wr2_flags_i(wr2_flags), .wr2_ready_i(wr2_ready_i), .wr2_ready_o(wr2_ready_o), + .wr3_data_i(wr3_dat), .wr3_flags_i(wr3_flags), .wr3_ready_i(wr3_ready_i), .wr3_ready_o(wr3_ready_o), // Read Interfaces - .rd0_dat_o(rd0_dat), .rd0_read_i(rd0_read), .rd0_done_i(rd0_done), - .rd0_error_i(rd0_error), .rd0_sop_o(rd0_sop), .rd0_eop_o(rd0_eop), - .rd1_dat_o(rd1_dat), .rd1_read_i(rd1_read), .rd1_done_i(rd1_done), - .rd1_error_i(rd1_error), .rd1_sop_o(rd1_sop), .rd1_eop_o(rd1_eop), - .rd2_dat_o(rd2_dat), .rd2_read_i(rd2_read), .rd2_done_i(rd2_done), - .rd2_error_i(rd2_error), .rd2_sop_o(rd2_sop), .rd2_eop_o(rd2_eop), - .rd3_dat_o(rd3_dat), .rd3_read_i(rd3_read), .rd3_done_i(rd3_done), - .rd3_error_i(rd3_error), .rd3_sop_o(rd3_sop), .rd3_eop_o(rd3_eop) + .rd0_data_o(rd0_dat), .rd0_flags_o(rd0_flags), .rd0_ready_i(rd0_ready_i), .rd0_ready_o(rd0_ready_o), + .rd1_data_o(rd1_dat), .rd1_flags_o(rd1_flags), .rd1_ready_i(rd1_ready_i), .rd1_ready_o(rd1_ready_o), + .rd2_data_o(rd2_dat), .rd2_flags_o(rd2_flags), .rd2_ready_i(rd2_ready_i), .rd2_ready_o(rd2_ready_o), + .rd3_data_o(rd3_dat), .rd3_flags_o(rd3_flags), .rd3_ready_i(rd3_ready_i), .rd3_ready_o(rd3_ready_o) ); // SPI -- Slave #2 @@ -398,11 +392,30 @@ module u2_core .word11(32'b0),.word12(32'b0),.word13(32'b0),.word14(32'b0),.word15(32'b0) ); - assign s5_err = 1'b0; - assign s5_rty = 1'b0; + assign s5_err = 1'b0; + assign s5_rty = 1'b0; + + // ///////////////////////////////////////////////////////////////////////// + // Ethernet MAC Slave #6 - // Slave, #6 Ethernet MAC, see below + simple_gemac_wrapper simple_gemac_wrapper + (.clk125(clk_to_mac), .reset(wb_rst), + .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN), + .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD), + .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV), + .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD), + .pause_req(0), .pause_time(0), + .sys_clk(dsp_clk), + .rx_f36_data({wr2_flags,wr2_dat}), .rx_f36_src_rdy(wr2_ready_i), .rx_f36_dst_rdy(wr2_ready_o), + .tx_f36_data({rd2_flags,rd2_dat}), .tx_f36_src_rdy(rd2_ready_o), .tx_f36_dst_rdy(rd2_ready_i), + .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(s6_stb), .wb_cyc(s6_cyc), .wb_ack(s6_ack), + .wb_we(s6_we), .wb_adr(s6_adr), .wb_dat_i(s6_dat_o), .wb_dat_o(s6_dat_i), + .mdio(MDIO), .mdc(MDC) ); + + assign s6_err = 1'b0; + assign s6_rty = 1'b0; + // ///////////////////////////////////////////////////////////////////////// // Settings Bus -- Slave #7 settings_bus settings_bus (.wb_clk(wb_clk),.wb_rst(wb_rst),.wb_adr_i(s7_adr),.wb_dat_i(s7_dat_o), @@ -448,55 +461,6 @@ module u2_core assign leds = (led_src & led_hw) | (~led_src & led_sw); // ///////////////////////////////////////////////////////////////////////// - // Ethernet MAC Slave #6 - - wire Tx_mac_wa, Tx_mac_wr, Tx_mac_sop, Tx_mac_eop; - wire Rx_mac_empty, Rx_mac_rd, Rx_mac_sop, Rx_mac_eop, Rx_mac_err; - wire [31:0] Tx_mac_data, Rx_mac_data; - wire [1:0] Tx_mac_BE, Rx_mac_BE; - wire rst_mac; - - oneshot_2clk mac_rst_1shot (.clk_in(wb_clk),.in(wb_rst),.clk_out(clk_to_mac),.out(rst_mac)); - - MAC_top #(.TX_FF_DEPTH(9), .RX_FF_DEPTH(11)) - MAC_top - (.Clk_125M(clk_to_mac),.Clk_user(dsp_clk), - .rst_mac(rst_mac),.rst_user(dsp_rst), - .RST_I(wb_rst),.CLK_I(wb_clk),.STB_I(s6_stb),.CYC_I(s6_cyc),.ADR_I(s6_adr[8:2]), - .WE_I(s6_we),.DAT_I(s6_dat_o),.DAT_O(s6_dat_i),.ACK_O(s6_ack), - .Rx_mac_empty(Rx_mac_empty),.Rx_mac_rd(Rx_mac_rd),.Rx_mac_data(Rx_mac_data),.Rx_mac_BE(Rx_mac_BE), - .Rx_mac_sop(Rx_mac_sop),.Rx_mac_eop(Rx_mac_eop),.Rx_mac_err(Rx_mac_err), - .Tx_mac_wa(Tx_mac_wa),.Tx_mac_wr(Tx_mac_wr),.Tx_mac_data(Tx_mac_data), - .Tx_mac_BE(Tx_mac_BE),.Tx_mac_sop(Tx_mac_sop),.Tx_mac_eop(Tx_mac_eop), - .Gtx_clk(GMII_GTX_CLK),.Tx_clk(GMII_TX_CLK),.Tx_er(GMII_TX_ER),.Tx_en(GMII_TX_EN),.Txd(GMII_TXD), - .Rx_clk(GMII_RX_CLK),.Rx_er(GMII_RX_ER),.Rx_dv(GMII_RX_DV),.Rxd(GMII_RXD), - .Crs(GMII_CRS),.Col(GMII_COL), - .Mdio(MDIO),.Mdc(MDC), - .rx_fifo_occupied(eth_rx_occ2),.rx_fifo_full(eth_rx_full2),.rx_fifo_empty(eth_rx_empty2), - .tx_fifo_occupied(),.tx_fifo_full(),.tx_fifo_empty(), - .debug0(debug_mac0),.debug1(debug_mac1) ); - - assign s6_err = 1'b0; - assign s6_rty = 1'b0; - - mac_rxfifo_int mac_rxfifo_int - (.clk(dsp_clk),.rst(dsp_rst), - .Rx_mac_empty(Rx_mac_empty),.Rx_mac_rd(Rx_mac_rd),.Rx_mac_data(Rx_mac_data), - .Rx_mac_BE(Rx_mac_BE),.Rx_mac_sop(Rx_mac_sop), - .Rx_mac_eop(Rx_mac_eop),.Rx_mac_err(Rx_mac_err), - .wr_dat_o(wr2_dat),.wr_write_o(wr2_write),.wr_done_o(wr2_done), - .wr_error_o(wr2_error),.wr_ready_i(wr2_ready),.wr_full_i(wr2_full), - .fifo_occupied(eth_rx_occ),.fifo_full(eth_rx_full),.fifo_empty(eth_rx_empty) ); - - mac_txfifo_int mac_txfifo_int - (.clk(dsp_clk),.rst(dsp_rst),.mac_clk(clk_to_mac), - .Tx_mac_wa(Tx_mac_wa),.Tx_mac_wr(Tx_mac_wr),.Tx_mac_data(Tx_mac_data), - .Tx_mac_BE(Tx_mac_BE),.Tx_mac_sop(Tx_mac_sop),.Tx_mac_eop(Tx_mac_eop), - .rd_dat_i(rd2_dat),.rd_read_o(rd2_read),.rd_done_o(rd2_done), - .rd_error_o(rd2_error),.rd_sop_i(rd2_sop),.rd_eop_i(rd2_eop), - .fifo_occupied(eth_tx_occ),.fifo_full(eth_tx_full),.fifo_empty(eth_tx_empty) ); - - // ///////////////////////////////////////////////////////////////////////// // Interrupt Controller, Slave #8 wire [15:0] irq={{4'b0, clk_status, serdes_link_up, uart_tx_int, uart_rx_int}, @@ -546,7 +510,7 @@ module u2_core (.clk_i(wb_clk),.rst_i(wb_rst), .adr_i(s11_adr[5:0]),.sel_i(s11_sel),.dat_i(s11_dat_o),.dat_o(s11_dat_i), .we_i(s11_we),.stb_i(s11_stb),.cyc_i(s11_cyc),.ack_o(s11_ack), - .run_rx(run_rx_d1),.run_tx(run_tx),.ctrl_lines(atr_lines) ); + .run_rx(run_rx_d1),.run_tx(run_tx),.master_time(), .ctrl_lines(atr_lines) ); assign s11_err = 0; assign s11_rty = 0; @@ -591,8 +555,7 @@ module u2_core (.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .master_time(master_time),.overrun(overrun), - .wr_dat_o(wr1_dat), .wr_write_o(wr1_write), .wr_done_o(wr1_done), .wr_error_o(wr1_error), - .wr_ready_i(wr1_ready), .wr_full_i(wr1_full), + .wr_dat_o(wr1_dat), .wr_flags_o(wr1_flags), .wr_ready_o(wr1_ready_i), .wr_ready_i(wr1_ready_o), .sample(sample_rx), .run(run_rx), .strobe(strobe_rx), .fifo_occupied(dsp_rx_occ),.fifo_full(dsp_rx_full),.fifo_empty(dsp_rx_empty), .debug_rx(debug_rx) ); @@ -602,15 +565,14 @@ module u2_core (.clk(dsp_clk),.rst(dsp_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .adc_a(adc_a),.adc_ovf_a(adc_ovf_a),.adc_b(adc_b),.adc_ovf_b(adc_ovf_b), - .io_rx(io_rx),.sample(sample_rx), .run(run_rx_d1), .strobe(strobe_rx), + .sample(sample_rx), .run(run_rx_d1), .strobe(strobe_rx), .debug(debug_rx_dsp) ); tx_control #(.FIFOSIZE(10)) tx_control (.clk(dsp_clk), .rst(dsp_rst), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .master_time(master_time),.underrun(underrun), - .rd_dat_i(rd1_dat), .rd_sop_i(rd1_sop), .rd_eop_i(rd1_eop), - .rd_read_o(rd1_read), .rd_done_o(rd1_done), .rd_error_o(rd1_error), + .rd_dat_i(rd1_dat), .rd_flags_i(rd_flags), .rd_ready_i(rd1_ready_o), .rd_ready_o(rd1_ready_i), .sample(sample_tx), .run(run_tx), .strobe(strobe_tx), .fifo_occupied(dsp_tx_occ),.fifo_full(dsp_tx_full),.fifo_empty(dsp_tx_empty), .debug(debug_txc) ); @@ -629,11 +591,9 @@ module u2_core serdes #(.TXFIFOSIZE(9),.RXFIFOSIZE(9)) serdes (.clk(dsp_clk),.rst(dsp_rst), .ser_tx_clk(ser_tx_clk),.ser_t(ser_t),.ser_tklsb(ser_tklsb),.ser_tkmsb(ser_tkmsb), - .rd_dat_i(rd0_dat),.rd_read_o(rd0_read),.rd_done_o(rd0_done),.rd_error_o(rd0_error), - .rd_sop_i(rd0_sop),.rd_eop_i(rd0_eop), + .rd_dat_i(rd0_dat),.rd_flags_i(rd0_flags),.rd_ready_o(rd0_ready_i),.rd_ready_i(rd0_ready_o), .ser_rx_clk(ser_rx_clk),.ser_r(ser_r),.ser_rklsb(ser_rklsb),.ser_rkmsb(ser_rkmsb), - .wr_dat_o(wr0_dat),.wr_write_o(wr0_write),.wr_done_o(wr0_done),.wr_error_o(wr0_error), - .wr_ready_i(wr0_ready),.wr_full_i(wr0_full), + .wr_dat_o(wr0_dat),.wr_flags_o(wr0_flags),.wr_ready_o(wr0_ready_i),.wr_ready_i(wr0_ready_o), .tx_occupied(ser_tx_occ),.tx_full(ser_tx_full),.tx_empty(ser_tx_empty), .rx_occupied(ser_rx_occ),.rx_full(ser_rx_full),.rx_empty(ser_rx_empty), .serdes_link_up(serdes_link_up),.debug0(debug_serdes0), .debug1(debug_serdes1) ); diff --git a/usrp2/fpga/top/u2_rev3/Makefile b/usrp2/fpga/top/u2_rev3/Makefile index c41ce7f77..5d782b610 100644 --- a/usrp2/fpga/top/u2_rev3/Makefile +++ b/usrp2/fpga/top/u2_rev3/Makefile @@ -56,14 +56,16 @@ export SOURCES := \ control_lib/CRC16_D16.v \ control_lib/atr_controller.v \ control_lib/bin2gray.v \ -control_lib/buffer_int.v \ -control_lib/buffer_pool.v \ +control_lib/newfifo/buffer_int.v \ +control_lib/newfifo/buffer_pool.v \ control_lib/cascadefifo2.v \ control_lib/dcache.v \ control_lib/decoder_3_8.v \ control_lib/dpram32.v \ control_lib/fifo_2clock.v \ control_lib/fifo_2clock_casc.v \ +control_lib/newfifo/newfifo_2clock.v \ +control_lib/newfifo/cascadefifo_2clock.v \ control_lib/gray2bin.v \ control_lib/gray_send.v \ control_lib/icache.v \ @@ -89,6 +91,22 @@ control_lib/oneshot_2clk.v \ control_lib/sd_spi.v \ control_lib/sd_spi_wb.v \ control_lib/wb_bridge_16_32.v \ +control_lib/reset_sync.v \ +simple_gemac/simple_gemac_wrapper.v \ +simple_gemac/simple_gemac.v \ +simple_gemac/simple_gemac_wb.v \ +simple_gemac/simple_gemac_tx.v \ +simple_gemac/simple_gemac_rx.v \ +simple_gemac/crc.v \ +simple_gemac/delay_line.v \ +simple_gemac/flow_ctrl_tx.v \ +simple_gemac/address_filter.v \ +control_lib/newfifo/ll8_shortfifo.v \ +control_lib/newfifo/ll8_to_fifo36.v \ +simple_gemac/ll8_to_txmac.v \ +simple_gemac/rxmac_to_ll8.v \ +control_lib/newfifo/fifo_short.v \ +control_lib/newfifo/fifo36_to_ll8.v \ coregen/fifo_xlnx_2Kx36_2clk.v \ coregen/fifo_xlnx_2Kx36_2clk.xco \ coregen/fifo_xlnx_512x36_2clk.v \ |