aboutsummaryrefslogtreecommitdiffstats
path: root/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v
diff options
context:
space:
mode:
Diffstat (limited to 'eth/rtl/verilog/MAC_rx/MAC_rx_FF.v')
-rw-r--r--eth/rtl/verilog/MAC_rx/MAC_rx_FF.v167
1 files changed, 167 insertions, 0 deletions
diff --git a/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v b/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v
new file mode 100644
index 000000000..e212b8986
--- /dev/null
+++ b/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v
@@ -0,0 +1,167 @@
+
+// ////////////////////////////////////////////////////////////////////
+// Completely Rewritten by M. Ettus, no John Gao code left
+// ////////////////////////////////////////////////////////////////////
+
+module MAC_rx_FF
+ #(parameter RX_FF_DEPTH = 9)
+ (input Reset,
+ input Clk_MAC,
+ input Clk_SYS,
+
+ // MAC_rx_ctrl interface
+ input [7:0] Fifo_data,
+ input Fifo_data_en,
+ output Fifo_full,
+ input Fifo_data_err,
+ input Fifo_data_end,
+ output [15:0] Fifo_space,
+
+ // CPU
+ input RX_APPEND_CRC,
+ input [4:0] Rx_Hwmark,
+ input [4:0] Rx_Lwmark,
+
+ // User interface
+ output Rx_mac_empty,
+ input Rx_mac_rd,
+ output [31:0] Rx_mac_data,
+ output [1:0] Rx_mac_BE,
+ output Rx_mac_sop,
+ output Rx_mac_eop,
+ output Rx_mac_err,
+
+ // FIFO Levels
+ output [15:0] fifo_occupied,
+ output fifo_full_dbg,
+ output fifo_empty
+ );
+
+ reg [1:0] FF_state;
+ reg [2:0] PKT_state;
+ reg [31:0] staging;
+ reg [35:0] staging2;
+ reg line_ready, line_ready_d1;
+ wire sop_i, eop_i;
+ reg [1:0] be;
+
+ always @(posedge Clk_MAC or posedge Reset)
+ if(Reset)
+ FF_state <= 0;
+ else
+ if(Fifo_data_err | Fifo_data_end)
+ FF_state <= 0;
+ else if(Fifo_data_en)
+ FF_state <= FF_state + 1;
+
+ always @(posedge Clk_MAC or posedge Reset)
+ if(Reset)
+ staging[31:0] <= 0;
+ else if(Fifo_data_en)
+ case(FF_state)
+ 0 : staging[31:24] <= Fifo_data;
+ 1 : staging[23:16] <= Fifo_data;
+ 2 : staging[15:8] <= Fifo_data;
+ 3 : staging[7:0] <= Fifo_data;
+ endcase // case(FF_state)
+
+ localparam PKT_idle = 0;
+ localparam PKT_sop = 1;
+ localparam PKT_pkt = 2;
+ localparam PKT_end = 3;
+ localparam PKT_err = 4;
+
+ always @(posedge Clk_MAC or posedge Reset)
+ if(Reset)
+ PKT_state <= 0;
+ else
+ case(PKT_state)
+ PKT_idle :
+ if(Fifo_data_en)
+ PKT_state <= PKT_sop;
+ PKT_sop, PKT_pkt :
+ if(Fifo_data_err | (line_ready & Fifo_full))
+ PKT_state <= PKT_err;
+ else if(Fifo_data_end)
+ PKT_state <= PKT_end;
+ else if(line_ready & ~Fifo_full)
+ PKT_state <= PKT_pkt;
+ PKT_end :
+ PKT_state <= PKT_idle;
+ PKT_err :
+ if(~Fifo_full)
+ PKT_state <= PKT_idle;
+ endcase // case(PKT_state)
+
+ assign sop_i = (PKT_state == PKT_sop);
+ assign eop_i = (PKT_state == PKT_end);
+
+ always @(posedge Clk_MAC)
+ if(line_ready)
+ staging2 <= {sop_i, eop_i, be[1:0], staging};
+
+ always @(posedge Clk_MAC)
+ if(Reset)
+ line_ready <= 0;
+ else if((Fifo_data_en & (FF_state==2'd3)) | Fifo_data_end | Fifo_data_err)
+ line_ready <= 1;
+ else
+ line_ready <= 0;
+
+ always @(posedge Clk_MAC)
+ line_ready_d1 <= line_ready;
+
+ always @(posedge Clk_MAC)
+ if(Fifo_data_end | Fifo_data_err)
+ be <= FF_state;
+ else
+ be <= 0;
+
+ wire sop_o, eop_o, empty;
+ wire [1:0] be_o;
+ wire [RX_FF_DEPTH-1:0] occupied, occupied_sysclk;
+ wire [31:0] dataout;
+
+/*
+ fifo_2clock #(.DWIDTH(36),.AWIDTH(RX_FF_DEPTH)) mac_rx_fifo
+ (.wclk(Clk_MAC),.datain((PKT_state==PKT_err) ? 36'hF_FFFF_FFFF : staging2),.write(~Fifo_full & (line_ready_d1|(PKT_state==PKT_err))),
+ .full(Fifo_full),.level_wclk(occupied),
+ .rclk(Clk_SYS),.dataout({sop_o,eop_o,be_o[1:0],dataout}),.read(Rx_mac_rd),
+ .empty(empty),.level_rclk(),
+ .arst(Reset) );
+ */
+
+ fifo_xlnx_2Kx36_2clk mac_rx_ff_core
+ (
+ .din((PKT_state==PKT_err) ? 36'hF_FFFF_FFFF : staging2), // Bus [35 : 0]
+ .rd_clk(Clk_SYS),
+ .rd_en(Rx_mac_rd),
+ .rst(Reset),
+ .wr_clk(Clk_MAC),
+ .wr_en(~Fifo_full & (line_ready_d1|(PKT_state==PKT_err))),
+ .dout({sop_o,eop_o,be_o[1:0],dataout}), // Bus [35 : 0]
+ .empty(empty),
+ .full(Fifo_full),
+ .rd_data_count(occupied_sysclk), // Bus [11 : 0]
+ .wr_data_count(occupied)); // Bus [11 : 0]
+
+ assign Fifo_space[15:RX_FF_DEPTH] = 0;
+ assign Fifo_space[RX_FF_DEPTH-1:0] = ~occupied;
+ assign fifo_occupied = occupied_sysclk;
+ assign fifo_full_dbg = Fifo_full; // FIXME -- in wrong clock domain
+ assign fifo_empty = empty;
+
+ // mac side fifo interface
+ // Input - Rx_mac_rd
+ // Output - Rx_mac_empty, Rx_mac_sop, Rx_mac_eop, Rx_mac_err, Rx_mac_data, Rx_mac_BE
+
+ assign Rx_mac_BE = be_o;
+ assign Rx_mac_sop = sop_o & ~eop_o;
+ assign Rx_mac_eop = eop_o;
+ assign Rx_mac_err = sop_o & eop_o;
+ assign Rx_mac_empty = empty;
+ assign Rx_mac_data = dataout;
+
+endmodule // MAC_rx_FF
+
+// FIXME Should we send out an "almost full" signal instead of full?