894d74a1195b2145252529fc2ea0c95e1baa6c71
[debian/gnuradio] / usrp2 / fpga / eth / tx_prot_engine.v
1
2 module tx_prot_engine
3   (input clk, input rst,
4    
5    // To MAC
6    input Tx_mac_wa,
7    output Tx_mac_wr,
8    output [31:0] Tx_mac_data,
9    output [1:0] Tx_mac_BE,
10    output Tx_mac_sop,
11    output Tx_mac_eop,
12
13    // To buffer interface
14    input [31:0] rd_dat_i,
15    output rd_read_o,
16    output rd_done_o,
17    output rd_error_o,
18    input rd_sop_i,
19    input rd_eop_i,
20
21    // To control
22    input set_stb,
23    input [7:0] set_addr,
24    input [31:0] set_data,
25
26    // Protocol Stuff
27    input [15:0] rx_fifo_status,
28    input [7:0] rx_seqnum
29    //input [7:0] tx_channel,
30    //input [7:0] tx_flags
31    );
32
33    wire [3:0]   hdr_adr;
34    wire [31:0]  hdr_dat;
35    wire [7:0]   tx_channel;
36    
37    header_ram #(.REGNUM(32),.WIDTH(32)) tx_header_ram
38      (.clk(clk),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
39       .addr(hdr_adr),.q(hdr_dat));
40
41    setting_reg #(.my_addr(32)) sr_channel
42      (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data),
43       .out(tx_channel),.changed());
44    
45    // Might as well use a shortfifo here since they are basically free
46    wire  empty, full, sfifo_write, sfifo_read;
47    wire [33:0] sfifo_in, sfifo_out;
48    
49    shortfifo #(.WIDTH(34)) txmac_sfifo
50      (.clk(clk),.rst(rst),.clear(0),
51       .datain(sfifo_in),.write(sfifo_write),.full(full),
52       .dataout(sfifo_out),.read(sfifo_read),.empty(empty));
53
54    // MAC side signals
55    // Inputs -- Tx_mac_wa, sfifo_out, empty
56    // outputs -- sfifo_read, Tx_mac_data, Tx_mac_wr, Tx_mac_BE, Tx_mac_sop, Tx_mac_eop
57    
58    //  We are allowed to do one more write after we are told the FIFO is full
59    //  This allows us to register the _wa signal and speed up timing.
60    reg         tx_mac_wa_d1;
61    always @(posedge clk)
62      tx_mac_wa_d1 <= Tx_mac_wa;
63
64    reg [2:0]   prot_state;
65    localparam  PROT_IDLE = 0;
66    localparam  PROT_HDR1 = 1;
67    localparam  PROT_HDR2 = 2;
68    localparam  PROT_HDR3 = 3;
69    localparam  PROT_HDR4 = 4;
70    localparam  PROT_HDR5 = 5;
71    localparam  PROT_PKT  = 6;
72
73    reg [7:0]   tx_seqnum;
74    reg         all_match;
75    always @(posedge clk)
76      if(rst) 
77        tx_seqnum <= 0;
78      else if(set_stb & (set_addr == 36))
79        tx_seqnum <= set_data[7:0];
80      else if(tx_mac_wa_d1 & all_match & (prot_state == PROT_HDR5))
81        tx_seqnum <= tx_seqnum + 1;
82    
83    always @(posedge clk)
84      if(rst)
85        prot_state <= PROT_IDLE;
86      else
87        if(tx_mac_wa_d1 & ~empty)
88          case(prot_state)
89            PROT_IDLE :
90              prot_state <= PROT_HDR1;
91            PROT_HDR1 :
92              prot_state <= PROT_HDR2;
93            PROT_HDR2 :
94              prot_state <= PROT_HDR3;
95            PROT_HDR3 :
96              prot_state <= PROT_HDR4;
97            PROT_HDR4 :
98              prot_state <= PROT_HDR5;
99            PROT_HDR5 :
100              prot_state <= PROT_PKT;
101            PROT_PKT :
102              if(sfifo_out[32] & ~empty)
103                prot_state <= PROT_IDLE;
104            default :
105              prot_state <= PROT_IDLE;
106          endcase // case(prot_state)
107
108    assign      hdr_adr = {1'b0,prot_state};
109    wire        match = (hdr_dat == sfifo_out[31:0]);   
110    always @(posedge clk)
111      if(prot_state == PROT_IDLE)
112        all_match <= 1;
113      else if(tx_mac_wa_d1 & ~empty &
114              ((prot_state==PROT_HDR1)|(prot_state==PROT_HDR2)|(prot_state==PROT_HDR3)))
115        all_match <= all_match & match;
116    
117    localparam  ETH_TYPE = 16'hBEEF;
118    assign      Tx_mac_data = 
119                ((prot_state == PROT_HDR5) & all_match) ? {rx_fifo_status,tx_seqnum,rx_seqnum} :
120                sfifo_out[31:0];
121    assign      sfifo_read = (prot_state != PROT_IDLE) & ~empty & tx_mac_wa_d1;
122    assign      Tx_mac_wr = sfifo_read;
123    assign      Tx_mac_BE = 0;  // Since we only deal with packets that are multiples of 32 bits long
124    assign      Tx_mac_sop = sfifo_out[33];
125    assign      Tx_mac_eop = sfifo_out[32];
126
127    // BUFFER side signals
128    reg         xfer_active;
129    always @(posedge clk)
130      if(rst)
131        xfer_active <= 0;
132      else if(rd_eop_i & ~full)
133        xfer_active <= 0;
134      else if(rd_sop_i)
135        xfer_active <= 1;
136    
137    assign      sfifo_in = {rd_sop_i, rd_eop_i, rd_dat_i};
138    assign      sfifo_write = xfer_active & ~full;
139
140    assign      rd_read_o = sfifo_write;
141    assign      rd_done_o = 0;  // Always send everything we're given?
142    assign      rd_error_o = 0;  // No possible error situations?
143    
144 endmodule // tx_prot_engine