diff options
Diffstat (limited to 'fpga/usrp1/inband_lib')
| -rwxr-xr-x | fpga/usrp1/inband_lib/chan_fifo_reader.v | 219 | ||||
| -rw-r--r-- | fpga/usrp1/inband_lib/channel_demux.v | 78 | ||||
| -rwxr-xr-x | fpga/usrp1/inband_lib/channel_ram.v | 107 | ||||
| -rwxr-xr-x | fpga/usrp1/inband_lib/cmd_reader.v | 305 | ||||
| -rwxr-xr-x | fpga/usrp1/inband_lib/packet_builder.v | 152 | ||||
| -rwxr-xr-x | fpga/usrp1/inband_lib/register_io.v | 82 | ||||
| -rwxr-xr-x | fpga/usrp1/inband_lib/rx_buffer_inband.v | 209 | ||||
| -rwxr-xr-x | fpga/usrp1/inband_lib/tx_buffer_inband.v | 143 | ||||
| -rw-r--r-- | fpga/usrp1/inband_lib/tx_packer.v | 119 | ||||
| -rwxr-xr-x | fpga/usrp1/inband_lib/usb_packet_fifo.v | 112 | 
10 files changed, 1526 insertions, 0 deletions
| diff --git a/fpga/usrp1/inband_lib/chan_fifo_reader.v b/fpga/usrp1/inband_lib/chan_fifo_reader.v new file mode 100755 index 000000000..69da9ec5a --- /dev/null +++ b/fpga/usrp1/inband_lib/chan_fifo_reader.v @@ -0,0 +1,219 @@ +module chan_fifo_reader  +   (reset, tx_clock, tx_strobe, timestamp_clock, samples_format, +    fifodata, pkt_waiting, rdreq, skip, tx_q, tx_i, +    underrun, tx_empty, debug, rssi, threshhold, rssi_wait) ; + +   input   wire                     reset ; +   input   wire                     tx_clock ; +   input   wire                     tx_strobe ; //signal to output tx_i and tx_q +   input   wire              [31:0] timestamp_clock ; //current time +   input   wire               [3:0] samples_format ;// not useful at this point +   input   wire              [31:0] fifodata ; //the data input +   input   wire                     pkt_waiting ; //signal the next packet is ready +   output  reg                      rdreq ; //actually an ack to the current fifodata +   output  reg                      skip ; //finish reading current packet +   output  reg               [15:0] tx_q ; //top 16 bit output of fifodata +   output  reg               [15:0] tx_i ; //bottom 16 bit output of fifodata +   output  reg                      underrun ;  +   output  reg                      tx_empty ; //cause 0 to be the output +   input   wire		     [31:0] rssi; +   input   wire		     [31:0] threshhold; +   input   wire		     [31:0] rssi_wait; + +   output wire [14:0] debug; +   assign debug = {7'd0, rdreq, skip, reader_state, pkt_waiting, tx_strobe, tx_clock}; +    +   //Samples format +   // 16 bits interleaved complex samples +   `define QI16                     4'b0 +     +   // States +   parameter IDLE           =     3'd0;     +   parameter HEADER         =     3'd1; +   parameter TIMESTAMP      =     3'd2; +   parameter WAIT           =     3'd3; +   parameter WAITSTROBE     =     3'd4; +   parameter SEND           =     3'd5; + +   // Header format +   `define PAYLOAD                  8:2 +   `define ENDOFBURST               27 +   `define STARTOFBURST             28 +   `define RSSI_FLAG                26 +	 + +   /* State registers */ +   reg                        [2:0] reader_state; +   /* Local registers */   +   reg                        [6:0] payload_len; +   reg                        [6:0] read_len; +   reg                       [31:0] timestamp; +   reg                              burst; +   reg                              trash; +   reg                              rssi_flag; +   reg			     [31:0] time_wait; +    +   always @(posedge tx_clock) +     begin +       if (reset)  +         begin +           reader_state <= IDLE; +           rdreq <= 0; +           skip <= 0; +           underrun <= 0; +           burst <= 0; +           tx_empty <= 1; +           tx_q <= 0; +           tx_i <= 0; +           trash <= 0; +           rssi_flag <= 0; +           time_wait <= 0; +         end +       else  +         begin +           case (reader_state) +             IDLE: +               begin +               /* +		* reset all the variables and wait for a tx_strobe +		* it is assumed that the ram connected to this fifo_reader  +		* is a short hand fifo meaning that the header to the next packet +		* is already available to this fifo_reader when pkt_waiting is on +		*/ +                 skip <=0; +                 time_wait <= 0; +                 if (pkt_waiting == 1) +                   begin +                     reader_state <= HEADER; +                     rdreq <= 1; +                     underrun <= 0; +                   end +                 if (burst == 1 && pkt_waiting == 0) +                     underrun <= 1; +                 if (tx_strobe == 1) +                     tx_empty <= 1 ; +               end + +               /* Process header */ +               HEADER: +                 begin +                   if (tx_strobe == 1) +                       tx_empty <= 1 ; +                    +                   rssi_flag <= fifodata[`RSSI_FLAG]&fifodata[`STARTOFBURST]; +                   //Check Start/End burst flag +                   if  (fifodata[`STARTOFBURST] == 1  +                       && fifodata[`ENDOFBURST] == 1) +                       burst <= 0; +                   else if (fifodata[`STARTOFBURST] == 1) +                       burst <= 1; +                   else if (fifodata[`ENDOFBURST] == 1) +                       burst <= 0; + +                   if (trash == 1 && fifodata[`STARTOFBURST] == 0) +                     begin +                       skip <= 1; +                       reader_state <= IDLE; +                       rdreq <= 0; +                     end  +                   else +                     begin    +                       payload_len <= fifodata[`PAYLOAD] ; +                       read_len <= 0; +                       rdreq <= 1; +                       reader_state <= TIMESTAMP; +                     end +                 end + +               TIMESTAMP:  +                 begin +                   timestamp <= fifodata; +                   reader_state <= WAIT; +                   if (tx_strobe == 1) +                       tx_empty <= 1 ; +                   rdreq <= 0; +                 end +				 +               // Decide if we wait, send or discard samples +               WAIT:  +                 begin +                   if (tx_strobe == 1) +                       tx_empty <= 1 ; +                     +                   time_wait <= time_wait + 32'd1; +                   // Outdated +                   if ((timestamp < timestamp_clock) || +                      (time_wait >= rssi_wait && rssi_wait != 0 && rssi_flag)) +                     begin +                       trash <= 1; +                       reader_state <= IDLE; +                       skip <= 1; +                     end   +                   // Let's send it					 +                   else if (timestamp == timestamp_clock  +                             || timestamp == 32'hFFFFFFFF) +                     begin +                       if (rssi <= threshhold || rssi_flag == 0) +                         begin +                           trash <= 0; +                           reader_state <= WAITSTROBE;  +                         end +                       else +                         reader_state <= WAIT; +                     end +                   else +                       reader_state <= WAIT; +                 end +                  +               // Wait for the transmit chain to be ready +               WAITSTROBE: +                 begin +                   // If end of payload... +                   if (read_len == payload_len) +                     begin +                       reader_state <= IDLE; +                       skip <= 1; +                       if (tx_strobe == 1) +                           tx_empty <= 1 ; +                     end   +                   else if (tx_strobe == 1) +                     begin +                       reader_state <= SEND; +                       rdreq <= 1; +                     end +                 end +                +               // Send the samples to the tx_chain +               SEND: +                 begin +                   reader_state <= WAITSTROBE;  +                   read_len <= read_len + 7'd1; +                   tx_empty <= 0; +                   rdreq <= 0; +                    +                   case(samples_format) +                       `QI16: +                        begin +                            tx_i <= fifodata[15:0]; +                            tx_q <= fifodata[31:16]; +                        end +                         +                        // Assume 16 bits complex samples by default +                        default: +                        begin +                            tx_i <= fifodata[15:0]; +                            tx_q <= fifodata[31:16]; +                        end  +                   endcase +                 end +                +               default: +                 begin +                   //error handling +                   reader_state <= IDLE; +                 end +           endcase +       end +   end +  +endmodule diff --git a/fpga/usrp1/inband_lib/channel_demux.v b/fpga/usrp1/inband_lib/channel_demux.v new file mode 100644 index 000000000..cca5cdb65 --- /dev/null +++ b/fpga/usrp1/inband_lib/channel_demux.v @@ -0,0 +1,78 @@ +module channel_demux + #(parameter NUM_CHAN = 2) (     //usb Side +   input [31:0]usbdata_final, +   input WR_final,  +   // TX Side +   input reset, +   input txclk, +   output reg [NUM_CHAN:0] WR_channel, +   output reg [31:0] ram_data, +   output reg [NUM_CHAN:0] WR_done_channel ); +   /* Parse header and forward to ram */ +	 +    reg [2:0]reader_state; +    reg [4:0]channel ; +    reg [6:0]read_length ; +	 +	 // States +    parameter IDLE      =    3'd0; +    parameter HEADER    =    3'd1; +    parameter WAIT      =    3'd2; +    parameter FORWARD   =    3'd3; +	 +	`define CHANNEL 20:16 +	`define PKT_SIZE 127 +	wire [4:0] true_channel; +	assign true_channel = (usbdata_final[`CHANNEL] == 5'h1f) ? +							NUM_CHAN : (usbdata_final[`CHANNEL]); +	 +	always @(posedge txclk) +	  begin +	    if (reset) +	      begin +	       reader_state <= IDLE; +	       WR_channel <= 0; +	       WR_done_channel <= 0; +	      end +	      else +	        case (reader_state) +	        IDLE: begin +	            if (WR_final) +	                reader_state <= HEADER;  +	            end +	        +            // Store channel and forware header +	        HEADER: begin +	            channel <= true_channel; +	            WR_channel[true_channel] <= 1; +	            ram_data <= usbdata_final; +				read_length <= 7'd0 ; +				 +                reader_state <= WAIT; +	        end +	        +	        WAIT: begin +	           WR_channel[channel] <= 0; +	 +			   if (read_length == `PKT_SIZE) +	               reader_state <= IDLE; +	           else if (WR_final) +	               reader_state <= FORWARD; +	        end +	        +	        FORWARD: begin +	           WR_channel[channel] <= 1; +	           ram_data <= usbdata_final; +	           read_length <= read_length + 7'd1; +	            +	           reader_state <= WAIT; +	        end +	 +			default: +               begin +					//error handling +                   reader_state <= IDLE; +               end +	       endcase +	   end +endmodule diff --git a/fpga/usrp1/inband_lib/channel_ram.v b/fpga/usrp1/inband_lib/channel_ram.v new file mode 100755 index 000000000..9621246c5 --- /dev/null +++ b/fpga/usrp1/inband_lib/channel_ram.v @@ -0,0 +1,107 @@ +module channel_ram  +   ( // System +     input txclk, input reset, +     // USB side +     input [31:0] datain, input WR, input WR_done, output have_space, +     // Reader side  +     output [31:0] dataout, input RD, input RD_done, output packet_waiting); +	 +   reg [6:0] wr_addr, rd_addr; +   reg [1:0] which_ram_wr, which_ram_rd; +   reg [2:0] nb_packets; +	 +   reg [31:0] ram0 [0:127]; +   reg [31:0] ram1 [0:127]; +   reg [31:0] ram2 [0:127]; +   reg [31:0] ram3 [0:127]; +	 +   reg [31:0] dataout0; +   reg [31:0] dataout1; +   reg [31:0] dataout2; +   reg [31:0] dataout3; +	 +   wire wr_done_int; +   wire rd_done_int; +   wire [6:0] rd_addr_final; +   wire [1:0] which_ram_rd_final; +	 +   // USB side +   always @(posedge txclk) +       if(WR & (which_ram_wr == 2'd0)) ram0[wr_addr] <= datain; +			 +   always @(posedge txclk) +       if(WR & (which_ram_wr == 2'd1)) ram1[wr_addr] <= datain; + +   always @(posedge txclk) +       if(WR & (which_ram_wr == 2'd2)) ram2[wr_addr] <= datain; + +   always @(posedge txclk) +       if(WR & (which_ram_wr == 2'd3)) ram3[wr_addr] <= datain; + +   assign wr_done_int = ((WR && (wr_addr == 7'd127)) || WR_done); +    +   always @(posedge txclk) +       if(reset) +           wr_addr <= 0; +       else if (WR_done) +           wr_addr <= 0; +       else if (WR)  +           wr_addr <= wr_addr + 7'd1; +		 +   always @(posedge txclk) +      if(reset) +          which_ram_wr <= 0; +      else if (wr_done_int)  +          which_ram_wr <= which_ram_wr + 2'd1; +	 +   assign have_space = (nb_packets < 3'd3); +		 +   // Reader side +   // short hand fifo +   // rd_addr_final is what rd_addr is going to be next clock cycle +   // which_ram_rd_final is what which_ram_rd is going to be next clock cycle +   always @(posedge txclk)  dataout0 <= ram0[rd_addr_final]; +   always @(posedge txclk)  dataout1 <= ram1[rd_addr_final]; +   always @(posedge txclk)  dataout2 <= ram2[rd_addr_final]; +   always @(posedge txclk)  dataout3 <= ram3[rd_addr_final]; +	 +   assign dataout = (which_ram_rd_final[1]) ?  +                    (which_ram_rd_final[0] ? dataout3 : dataout2) : +                    (which_ram_rd_final[0] ? dataout1 : dataout0); + +   //RD_done is the only way to signal the end of one packet +   assign rd_done_int = RD_done;    + +   always @(posedge txclk) +       if (reset) +           rd_addr <= 0; +       else if (RD_done) +           rd_addr <= 0; +       else if (RD)  +           rd_addr <= rd_addr + 7'd1; +			 +   assign rd_addr_final = (reset|RD_done) ? (6'd0) :  +	                  ((RD)?(rd_addr+7'd1):rd_addr);  +	 +   always @(posedge txclk) +       if (reset) +           which_ram_rd <= 0; +       else if (rd_done_int) +           which_ram_rd <= which_ram_rd + 2'd1; + +   assign which_ram_rd_final = (reset) ? (2'd0): +	                       ((rd_done_int) ? (which_ram_rd + 2'd1) : which_ram_rd); +	                         +   //packet_waiting is set to zero if rd_done_int is high +   //because there is no guarantee that nb_packets will be pos. + +   assign packet_waiting = (nb_packets > 1) | ((nb_packets == 1)&(~rd_done_int)); +   always @(posedge txclk) +       if (reset) +           nb_packets <= 0; +       else if (wr_done_int & ~rd_done_int) +           nb_packets <= nb_packets + 3'd1; +       else if (rd_done_int & ~wr_done_int) +           nb_packets <= nb_packets - 3'd1; +			 +endmodule diff --git a/fpga/usrp1/inband_lib/cmd_reader.v b/fpga/usrp1/inband_lib/cmd_reader.v new file mode 100755 index 000000000..b69ea02b7 --- /dev/null +++ b/fpga/usrp1/inband_lib/cmd_reader.v @@ -0,0 +1,305 @@ +module cmd_reader +   (//System +    input reset, input txclk, input [31:0] timestamp_clock, +    //FX2 Side +    output reg skip, output reg rdreq,  +    input [31:0] fifodata, input pkt_waiting, +    //Rx side +    input rx_WR_enabled, output reg [15:0] rx_databus, +    output reg rx_WR, output reg rx_WR_done, +    //register io +    input wire [31:0] reg_data_out, output reg [31:0] reg_data_in, +    output reg [6:0] reg_addr, output reg [1:0] reg_io_enable, +    output wire [14:0] debug, output reg stop, output reg [15:0] stop_time); +	 +   // States +   parameter IDLE                       =   4'd0; +   parameter HEADER                     =   4'd1; +   parameter TIMESTAMP                  =   4'd2; +   parameter WAIT          	        =   4'd3; +   parameter TEST                       =   4'd4; +   parameter SEND                       =   4'd5; +   parameter PING                       =   4'd6; +   parameter WRITE_REG                  =   4'd7; +   parameter WRITE_REG_MASKED           =   4'd8; +   parameter READ_REG                   =   4'd9; +   parameter DELAY                      =   4'd14;		 + +   `define OP_PING_FIXED                    8'd0 +   `define OP_PING_FIXED_REPLY              8'd1 +   `define OP_WRITE_REG	                    8'd2 +   `define OP_WRITE_REG_MASKED              8'd3 +   `define OP_READ_REG                      8'd4 +   `define OP_READ_REG_REPLY                8'd5 +   `define OP_DELAY                         8'd12 +	 +   reg [6:0]   payload; +   reg [6:0]   payload_read; +   reg [3:0]   state; +   reg [15:0]  high; +   reg [15:0]  low; +   reg         pending; +   reg [31:0]  value0; +   reg [31:0]  value1; +   reg [31:0]  value2; +   reg [1:0]   lines_in; +   reg [1:0]   lines_out; +   reg [1:0]   lines_out_total; +	 +   `define JITTER                           5 +   `define OP_CODE                          31:24 +   `define PAYLOAD                          8:2 +	 +   wire [7:0] ops; +   assign ops = value0[`OP_CODE]; +   assign debug = {state[3:0], lines_out[1:0], pending, rx_WR, rx_WR_enabled, value0[2:0], ops[2:0]}; +	 +   always @(posedge txclk) +       if (reset) +         begin +           pending <= 0; +           state <= IDLE; +           skip <= 0; +           rdreq <= 0; +           rx_WR <= 0; +           reg_io_enable <= 0; +           reg_data_in <= 0; +           reg_addr <= 0; +           stop <= 0; +          end +        else case (state) +          IDLE :  +            begin +              payload_read <= 0; +              skip <= 0; +              lines_in <= 0; +              if(pkt_waiting) +                begin +                  state <= HEADER; +                  rdreq <= 1; +                end +             end +           +          HEADER :  +            begin +              payload <= fifodata[`PAYLOAD]; +              state <= TIMESTAMP; +            end +           +          TIMESTAMP :  +            begin +              value0 <= fifodata; +              state <= WAIT; +              rdreq <= 0; +            end +			 +          WAIT :  +            begin +              // Let's send it +              if ((value0 <= timestamp_clock + `JITTER  +                 && value0 > timestamp_clock) +                 || value0 == 32'hFFFFFFFF) +                  state <= TEST; +              // Wait a little bit more +              else if (value0 > timestamp_clock + `JITTER) +                  state <= WAIT;  +              // Outdated +              else if (value0 < timestamp_clock) +                begin +                  state <= IDLE; +                  skip <= 1; +                end +            end +			 +          TEST :  +            begin +              reg_io_enable <= 0; +              rx_WR <= 0; +              rx_WR_done <= 1; +              stop <= 0; +              if (payload_read == payload) +                begin +                  skip <= 1; +                  state <= IDLE; +                  rdreq <= 0; +                end +              else +                begin +                  value0 <= fifodata; +                  lines_in <= 2'd1; +                  rdreq <= 1; +                  payload_read <= payload_read + 7'd1; +                  lines_out <= 0; +                  case (fifodata[`OP_CODE]) +                    `OP_PING_FIXED:  +                      begin +                        state <= PING; +                      end +                    `OP_WRITE_REG:  +                      begin +                        state <= WRITE_REG; +                        pending <= 1; +                      end +                    `OP_WRITE_REG_MASKED:  +                      begin +                        state <= WRITE_REG_MASKED; +                        pending <= 1; +                      end +                    `OP_READ_REG:  +                      begin +                        state <= READ_REG; +                      end +                    `OP_DELAY:  +                      begin +                        state <= DELAY; +                      end +                    default:  +                      begin +                      //error, skip this packet +                        skip <= 1; +                        state <= IDLE; +                      end +                  endcase +                end +              end +			 +            SEND:  +              begin +                rdreq <= 0; +                rx_WR_done <= 0; +                if (pending) +                  begin +                    rx_WR <= 1; +                    rx_databus <= high; +                    pending <= 0; +                    if (lines_out == lines_out_total) +                        state <= TEST; +                    else case (ops) +                        `OP_READ_REG:  +                          begin +                            state <= READ_REG; +                          end +                         default:  +                           begin +                             state <= TEST; +                           end +                    endcase +                  end +                else +                  begin +                    if (rx_WR_enabled) +                      begin +                        rx_WR <= 1; +                        rx_databus <= low; +                        pending <= 1; +                        lines_out <= lines_out + 2'd1; +                      end +                    else +                        rx_WR <= 0; +                  end +                end +			 +            PING:  +              begin +                rx_WR <= 0; +                rdreq <= 0; +                rx_WR_done <= 0; +                lines_out_total <= 2'd1; +                pending <= 0;  +                state <= SEND; +                high <= {`OP_PING_FIXED_REPLY, 8'd2}; +                low <= value0[15:0];	 +              end +			 +            READ_REG:  +              begin +                rx_WR <= 0; +                rx_WR_done <= 0; +                rdreq <= 0; +                lines_out_total <= 2'd2; +                pending <= 0; +                state <= SEND; +                if (lines_out == 0) +                  begin +                    high <= {`OP_READ_REG_REPLY, 8'd6}; +                    low <= value0[15:0]; +                    reg_io_enable <= 2'd3; +                    reg_addr <= value0[6:0]; +                  end +                else +                  begin		 +                    high <= reg_data_out[31:16]; +                    low <= reg_data_out[15:0]; +                  end +             end     +			 +            WRITE_REG:  +              begin +                rx_WR <= 0; +                if (pending) +                    pending <= 0; +                else +                  begin +                    if (lines_in == 2'd1) +                      begin +                        payload_read <= payload_read + 7'd1; +                        lines_in <= lines_in + 2'd1; +                        value1 <= fifodata; +                        rdreq <= 0; +                      end +                    else +                      begin +                        reg_io_enable <= 2'd2; +                        reg_data_in <= value1; +                        reg_addr <= value0[6:0]; +                        state <= TEST; +                      end +                  end +              end +			 +            WRITE_REG_MASKED:  +              begin +                rx_WR <= 0; +                if (pending) +                    pending <= 0; +                else +                  begin +                    if (lines_in == 2'd1) +                      begin +                        rdreq <= 1; +                        payload_read <= payload_read + 7'd1; +                        lines_in <= lines_in + 2'd1; +                        value1 <= fifodata; +                      end +                    else if (lines_in == 2'd2) +                      begin +                        rdreq <= 0; +                        payload_read <= payload_read + 7'd1; +                        lines_in <= lines_in + 2'd1; +                        value2 <= fifodata; +                      end +                    else +                      begin +                        reg_io_enable <= 2'd2; +                        reg_data_in <= (value1 & value2); +                        reg_addr <= value0[6:0]; +                        state <= TEST; +                      end +                  end +              end +			 +            DELAY :  +              begin +                rdreq <= 0; +                stop <= 1; +                stop_time <= value0[15:0]; +                state <= TEST; +              end +			 +            default :  +              begin +                //error state handling +                state <= IDLE; +              end +        endcase +endmodule diff --git a/fpga/usrp1/inband_lib/packet_builder.v b/fpga/usrp1/inband_lib/packet_builder.v new file mode 100755 index 000000000..2c9122394 --- /dev/null +++ b/fpga/usrp1/inband_lib/packet_builder.v @@ -0,0 +1,152 @@ +module packet_builder #(parameter NUM_CHAN = 2)( +    // System +    input rxclk, +    input reset, +	 input [31:0] timestamp_clock, +	 input [3:0] channels, +    // ADC side +    input [15:0]chan_fifodata, +    input [NUM_CHAN:0]chan_empty, +    input [9:0]chan_usedw, +    output reg [3:0]rd_select, +    output reg chan_rdreq, +    // FX2 side +    output reg WR, +    output reg [15:0]fifodata, +    input have_space,  +    input wire [31:0]rssi_0, input wire [31:0]rssi_1, input wire [31:0]rssi_2, +    input wire [31:0]rssi_3, output wire [7:0] debugbus, +    input [NUM_CHAN:0] underrun); +     +     +    // States +    `define IDLE                     3'd0 +    `define HEADER1                  3'd1 +    `define HEADER2                  3'd2 +    `define TIMESTAMP                3'd3 +    `define FORWARD                  3'd4 +	 +    `define MAXPAYLOAD 504 +     +    `define PAYLOAD_LEN 8:0 +    `define TAG 12:9 +    `define MBZ 15:13 +     +    `define CHAN 4:0 +    `define RSSI 10:5 +    `define BURST 12:11 +    `define DROPPED 13 +    `define UNDERRUN 14 +    `define OVERRUN 15 +     +    reg [NUM_CHAN:0] overrun; +    reg [2:0] state; +    reg [8:0] read_length; +    reg [8:0] payload_len; +    reg timestamp_complete; +    reg [3:0] check_next; +	 +    wire [31:0] true_rssi; +    wire [4:0] true_channel; +    wire ready_to_send; + +    assign debugbus = {chan_empty[0], rd_select[0], have_space,  +                       (chan_usedw >= 10'd504), (chan_usedw ==0),   +                       ready_to_send, state[1:0]}; + +    assign true_rssi = (rd_select[1]) ? ((rd_select[0]) ? rssi_3:rssi_2) : +							((rd_select[0]) ? rssi_1:rssi_0); +    assign true_channel = (check_next == 4'd0 ? 5'h1f : {1'd0, check_next - 4'd1}); +    assign ready_to_send = (chan_usedw >= 10'd504) || (chan_usedw == 0) ||  +                           ((rd_select == NUM_CHAN)&&(chan_usedw > 0)); +		 +    always @(posedge rxclk) +    begin +        if (reset) +          begin +            overrun <= 0; +            WR <= 0; +            rd_select <= 0; +            chan_rdreq <= 0; +            timestamp_complete <= 0; +            check_next <= 0; +            state <= `IDLE; +          end +        else case (state) +            `IDLE: begin +		chan_rdreq <= #1 0; +		//check if the channel is full +		if(~chan_empty[check_next]) +		  begin +                    if (have_space) +                      begin +                        //transmit if the usb buffer have space +                       //check if we should send +                       if (ready_to_send) +                           state <= #1 `HEADER1; +						     +                       overrun[check_next] <= 0; +                      end +                  else +                    begin +                      state <= #1 `IDLE; +                      overrun[check_next] <= 1; +                    end +                  rd_select <= #1 check_next; +                end +                check_next <= #1 (check_next == channels ? 4'd0 : check_next + 4'd1); +            end +             +            `HEADER1: begin +                fifodata[`PAYLOAD_LEN] <= #1 9'd504; +                payload_len <= #1 9'd504; +                fifodata[`TAG] <= #1 0; +                fifodata[`MBZ] <= #1 0; +                WR <= #1 1; +                 +                state <= #1 `HEADER2; +                read_length <= #1 0; +            end +             +            `HEADER2: begin +                fifodata[`CHAN] <= #1 true_channel; +                fifodata[`RSSI] <= #1 true_rssi[5:0]; +                fifodata[`BURST] <= #1 0; +                fifodata[`DROPPED] <= #1 0; +                fifodata[`UNDERRUN] <= #1 (check_next == 0) ? 1'b0 : underrun[true_channel]; +                fifodata[`OVERRUN] <= #1 (check_next == 0) ? 1'b0 : overrun[true_channel]; +                state <= #1 `TIMESTAMP; +            end +             +            `TIMESTAMP: begin +                fifodata <= #1 (timestamp_complete ? timestamp_clock[31:16] : timestamp_clock[15:0]); +                timestamp_complete <= #1 ~timestamp_complete; +                 +                if (~timestamp_complete) +                    chan_rdreq <= #1 1; +                 +                state <= #1 (timestamp_complete ? `FORWARD : `TIMESTAMP); +            end +             +            `FORWARD: begin +                read_length <= #1 read_length + 9'd2; +                fifodata <= #1 (read_length >= payload_len ? 16'hDEAD : chan_fifodata); +                 +                if (read_length >= `MAXPAYLOAD) +                  begin +                    WR <= #1 0; +                    state <= #1 `IDLE; +					chan_rdreq <= #1 0; +                  end +                else if (read_length == payload_len - 4) +                    chan_rdreq <= #1 0; +            end +             +            default: begin +				//handling error state +                state <= `IDLE; +            end +            endcase +    end +endmodule + diff --git a/fpga/usrp1/inband_lib/register_io.v b/fpga/usrp1/inband_lib/register_io.v new file mode 100755 index 000000000..2b0cd1732 --- /dev/null +++ b/fpga/usrp1/inband_lib/register_io.v @@ -0,0 +1,82 @@ +module register_io +	(clk, reset, enable, addr, datain, dataout, debugbus, addr_wr, data_wr, strobe_wr, +	 rssi_0, rssi_1, rssi_2, rssi_3, threshhold, rssi_wait, reg_0, reg_1, reg_2, reg_3,  +     debug_en, misc, txmux);    +	 +	input clk; +	input reset; +	input wire [1:0] enable; +	input wire [6:0] addr;  +	input wire [31:0] datain; +	output reg [31:0] dataout; +	output wire [15:0] debugbus; +	output reg [6:0] addr_wr; +	output reg [31:0] data_wr; +	output wire strobe_wr;  +	input wire [31:0] rssi_0; +	input wire [31:0] rssi_1; +	input wire [31:0] rssi_2;  +	input wire [31:0] rssi_3;  +	output wire [31:0] threshhold; +	output wire [31:0] rssi_wait; +	input wire [15:0] reg_0; +	input wire [15:0] reg_1;  +	input wire [15:0] reg_2;  +	input wire [15:0] reg_3; +	input wire [3:0]  debug_en; +	input wire [7:0]  misc; +	input wire [31:0] txmux; +	 +	reg strobe; +	wire [31:0] out[2:1]; +	assign debugbus = {clk, enable, addr[2:0], datain[4:0], dataout[4:0]}; +	assign threshhold = out[1]; +	assign rssi_wait = out[2]; +	assign strobe_wr = strobe; +	 +	always @(*) +        if (reset | ~enable[1]) +           begin +             strobe <= 0; +		     dataout <= 0; +		   end +		else +		   begin +	         if (enable[0]) +	           begin +	             //read +				if (addr <= 7'd52 && addr > 7'd50) +					dataout <= out[addr-7'd50]; +				else +					dataout <= 32'hFFFFFFFF; 	 +	            strobe <= 0; +              end +             else +               begin +                 //write +	             dataout <= dataout; +                 strobe <= 1; +				 data_wr <= datain; +				 addr_wr <= addr; +               end +          end + +//register declarations +    /*setting_reg #(50) setting_reg0(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[0]));*/ +    setting_reg #(51) setting_reg1(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[1])); +    setting_reg #(52) setting_reg2(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[2])); +    /*setting_reg #(53) setting_reg3(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[3])); +    setting_reg #(54) setting_reg4(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[4])); +    setting_reg #(55) setting_reg5(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[5])); +    setting_reg #(56) setting_reg6(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[6])); +    setting_reg #(57) setting_reg7(.clock(clk),.reset(reset), +    .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[7]));*/ + +endmodule	 diff --git a/fpga/usrp1/inband_lib/rx_buffer_inband.v b/fpga/usrp1/inband_lib/rx_buffer_inband.v new file mode 100755 index 000000000..cbd2d8958 --- /dev/null +++ b/fpga/usrp1/inband_lib/rx_buffer_inband.v @@ -0,0 +1,209 @@ +//`include "../../firmware/include/fpga_regs_common.v"
 +//`include "../../firmware/include/fpga_regs_standard.v"
 +module rx_buffer_inband
 +  ( input usbclk,
 +    input bus_reset,
 +    input reset,  // DSP side reset (used here), do not reset registers
 +    input reset_regs, //Only reset registers
 +    output [15:0] usbdata,
 +    input RD,
 +    output wire have_pkt_rdy,
 +    output reg rx_overrun,
 +    input wire [3:0] channels,
 +    input wire [15:0] ch_0,
 +    input wire [15:0] ch_1,
 +    input wire [15:0] ch_2,
 +    input wire [15:0] ch_3,
 +    input wire [15:0] ch_4,
 +    input wire [15:0] ch_5,
 +    input wire [15:0] ch_6,
 +    input wire [15:0] ch_7,
 +    input rxclk,
 +    input rxstrobe,
 +    input clear_status,
 +    input [6:0] serial_addr, 
 +    input [31:0] serial_data, 
 +    input serial_strobe,
 +    output wire [15:0] debugbus,
 +	
 +    //Connection with tx_inband
 +    input rx_WR,
 +    input [15:0] rx_databus,
 +    input rx_WR_done,
 +    output reg rx_WR_enabled,
 +    //signal strength
 +    input wire [31:0] rssi_0, input wire [31:0] rssi_1,
 +    input wire [31:0] rssi_2, input wire [31:0] rssi_3,
 +    input wire [1:0] tx_underrun
 +    );
 +    
 +    parameter NUM_CHAN = 1;
 +    genvar i ;
 +    
 +    // FX2 Bug Fix
 +    reg [8:0] read_count;
 +    always @(negedge usbclk)
 +        if(bus_reset)
 +            read_count <= #1 9'd0;
 +        else if(RD & ~read_count[8])
 +            read_count <= #1 read_count + 9'd1;
 +        else
 +            read_count <= #1 RD ? read_count : 9'b0;
 +       
 +	// Time counter
 +	reg [31:0] timestamp_clock;
 +	always @(posedge rxclk)
 +		if (reset)
 +			timestamp_clock <= 0;
 +		else
 +			timestamp_clock <= timestamp_clock + 1;
 +     
 +  // USB side fifo
 +  wire [11:0] rdusedw;
 +  wire [11:0] wrusedw;
 +  wire [15:0] fifodata;
 +  wire [15:0] fifodata_il[0:NUM_CHAN];
 +  wire WR;
 +  wire have_space;
 +  reg sel;
 +  reg wr;
 +
 +  always@(posedge rxclk)
 +    begin
 +      if(reset)
 +        begin
 +          sel<=1;
 +          wr<=0;
 +        end
 +      else if(rxstrobe)
 +        begin
 +          sel<=0;
 +          wr<=1;
 +        end
 +      else if(wr&~sel)
 +          sel<=1;
 +      else if(wr&sel)
 +          wr<=0;
 +      else
 +          wr<=0;
 +    end
 +
 +  assign fifodata_il[0] = (sel)?ch_1:ch_0;
 +  assign fifodata_il[1] = (sel)?ch_3:ch_2;
 +
 +  fifo_4kx16_dc	rx_usb_fifo (
 +    .aclr ( reset ),
 +    .data ( fifodata ),
 +    .rdclk ( ~usbclk ),
 +    .rdreq ( RD & ~read_count[8] ),
 +    .wrclk ( rxclk ),
 +    .wrreq ( WR ),
 +    .q ( usbdata ),
 +    .rdempty (  ),
 +    .rdusedw ( rdusedw ),
 +    .wrfull (  ),
 +    .wrusedw ( wrusedw ) );
 +    
 +  assign have_pkt_rdy = (rdusedw >= 12'd256);
 +  assign have_space = (wrusedw < 12'd760);
 +	 
 +  // Rx side fifos
 +  // These are of size [NUM_CHAN:0] because the extra channel is used for the
 +  // RX command channel.  If there were no command channel, they would be
 +  // NUM_CHAN-1.
 +  wire chan_rdreq;
 +  wire [15:0] chan_fifodata;
 +  wire [9:0] chan_usedw;
 +  wire [NUM_CHAN:0] chan_empty;
 +  wire [3:0] rd_select;
 +  wire [NUM_CHAN:0] rx_full;
 +	 
 +  packet_builder #(NUM_CHAN) rx_pkt_builer (
 +    .rxclk ( rxclk ),
 +    .reset ( reset ),
 +    .timestamp_clock ( timestamp_clock ),
 +    .channels ( NUM_CHAN ),
 +    .chan_rdreq ( chan_rdreq ),
 +    .chan_fifodata ( chan_fifodata ),
 +    .chan_empty ( chan_empty ),
 +    .rd_select ( rd_select ),
 +    .chan_usedw ( chan_usedw ),
 +    .WR ( WR ),
 +    .fifodata ( fifodata ),
 +    .have_space ( have_space ),
 +      .rssi_0(rssi_0), .rssi_1(rssi_1),
 +      .rssi_2(rssi_2),.rssi_3(rssi_3), .debugbus(debug),
 +      .underrun(tx_underrun));
 +	 
 +  // Detect overrun
 +  always @(posedge rxclk)
 +    if(reset)
 +      rx_overrun <= 1'b0;
 +    else if(rx_full[0])
 +      rx_overrun <= 1'b1;
 +    else if(clear_status)
 +      rx_overrun <= 1'b0;
 +
 +		
 +  // FIXME: what is the purpose of these two lines?
 +  wire [15:0]ch[NUM_CHAN:0];
 +  assign ch[0] = ch_0;
 +	
 +  wire cmd_empty;
 +	
 +  always @(posedge rxclk)
 +    if(reset)
 +      rx_WR_enabled <= 1;
 +    else if(cmd_empty)
 +      rx_WR_enabled <= 1;
 +    else if(rx_WR_done)
 +      rx_WR_enabled <= 0;
 +
 +
 +  // Of Size 0:NUM_CHAN due to extra command channel.
 +  wire [15:0] dataout [0:NUM_CHAN];
 +  wire [9:0]  usedw	[0:NUM_CHAN];
 +  wire empty[0:NUM_CHAN];
 +	
 +  generate for (i = 0 ; i < NUM_CHAN; i = i + 1)
 +    begin : generate_channel_fifos
 +
 +      wire rdreq;
 +
 +      assign rdreq = (rd_select == i) & chan_rdreq;
 +
 +      fifo_1kx16 rx_chan_fifo (
 +      .aclr ( reset ),
 +      .clock ( rxclk ),
 +      .data ( fifodata_il[i] ),
 +      .rdreq ( rdreq ),
 +      .wrreq ( ~rx_full[i] & wr),
 +      .empty (empty[i]),
 +      .full (rx_full[i]),
 +      .q ( dataout[i]),
 +      .usedw ( usedw[i]),
 +      .almost_empty(chan_empty[i])
 +      );
 +    end
 +  endgenerate
 +	
 +  wire [7:0] debug;
 +	 
 +  fifo_1kx16 rx_cmd_fifo (
 +    .aclr ( reset ),
 +    .clock ( rxclk ),
 +    .data ( rx_databus ),
 +    .rdreq ( (rd_select == NUM_CHAN) & chan_rdreq ),
 +    .wrreq ( rx_WR & rx_WR_enabled),
 +    .empty ( cmd_empty),
 +    .full ( rx_full[NUM_CHAN] ),
 +    .q ( dataout[NUM_CHAN]),
 +    .usedw ( usedw[NUM_CHAN] )
 +  );
 +	
 +  assign chan_empty[NUM_CHAN] = cmd_empty | rx_WR_enabled;
 +  assign chan_fifodata = dataout[rd_select];
 +  assign chan_usedw = usedw[rd_select];
 +  assign debugbus = {4'd0, rxclk, rxstrobe, rx_full[0], rx_full[1], sel, wr};
 +
 +endmodule
 diff --git a/fpga/usrp1/inband_lib/tx_buffer_inband.v b/fpga/usrp1/inband_lib/tx_buffer_inband.v new file mode 100755 index 000000000..2dd75f42f --- /dev/null +++ b/fpga/usrp1/inband_lib/tx_buffer_inband.v @@ -0,0 +1,143 @@ +module tx_buffer_inband +  ( //System +    input wire usbclk, input wire bus_reset, input wire reset,  +    input wire [15:0] usbdata, output wire have_space, input wire [3:0] channels,  +    //output transmit signals +    output wire [15:0] tx_i_0, output wire [15:0] tx_q_0,  +    output wire [15:0] tx_i_1, output wire [15:0] tx_q_1, +    output wire [15:0] tx_i_2, output wire [15:0] tx_q_2,  +    output wire [15:0] tx_i_3, output wire [15:0] tx_q_3,  +    input wire txclk, input wire txstrobe, input wire WR, +    input wire clear_status, output wire tx_empty, output wire [15:0] debugbus,  +    //command reader io +    output wire [15:0] rx_databus, output wire rx_WR, output wire rx_WR_done,  +    input wire rx_WR_enabled, +    //register io  +    output wire [1:0] reg_io_enable, output wire [31:0] reg_data_in, output wire [6:0] reg_addr, +    input wire [31:0] reg_data_out,   +    //input characteristic signals +    input wire [31:0] rssi_0, input wire [31:0] rssi_1, input wire [31:0] rssi_2,  +    input wire [31:0] rssi_3, input wire [31:0] rssi_wait, input wire [31:0] threshhold,  +    output wire [1:0] tx_underrun,  +    //system stop +    output wire stop, output wire [15:0] stop_time); +	 +   parameter NUM_CHAN	 =      1 ; +     +   /* To generate channel readers */ +   genvar i ; +     +   /* These will eventually be external register */ +   reg                  [31:0] timestamp_clock ; +   wire                 [7:0]  txstrobe_rate [NUM_CHAN-1:0] ; +   wire			        [31:0] rssi [3:0]; +   assign rssi[0] = rssi_0; +   assign rssi[1] = rssi_1; +   assign rssi[2] = rssi_2; +   assign rssi[3] = rssi_3; +    +   always @(posedge txclk) +       if (reset) +           timestamp_clock <= 0; +       else +           timestamp_clock <= timestamp_clock + 1; + + +    /* Connections between tx_usb_fifo_reader and +       cnannel/command processing blocks */ +   wire                  [31:0] tx_data_bus ; +   wire            [NUM_CHAN:0] chan_WR ; +   wire            [NUM_CHAN:0] chan_done ; +     +    /* Connections between data block and the +       FX2/TX chains */ +   wire            [NUM_CHAN:0] chan_underrun; +   wire            [NUM_CHAN:0] chan_txempty; +    +   /* Conections between tx_data_packet_fifo and +       its reader + strobe generator */ +   wire                 [31:0] chan_fifodata [NUM_CHAN:0] ; +   wire                        chan_pkt_waiting [NUM_CHAN:0] ; +   wire                        chan_rdreq [NUM_CHAN:0] ; +   wire                        chan_skip [NUM_CHAN:0] ; +   wire                        chan_have_space [NUM_CHAN:0] ; + +   wire		            [14:0] debug [NUM_CHAN:0]; +     +   /* Outputs to transmit chains */ +   wire                 [15:0] tx_i [NUM_CHAN:0] ; +   wire                 [15:0] tx_q [NUM_CHAN:0] ; + +   assign tx_i[NUM_CHAN] = 0; +   assign tx_q[NUM_CHAN] = 0; +     +   assign have_space = chan_have_space[0] & chan_have_space[1]; +   assign tx_empty = chan_txempty[0] & chan_txempty[1] ; + +   assign tx_i_0 = chan_txempty[0] ? 16'b0 : tx_i[0] ; +   assign tx_q_0 = chan_txempty[0] ? 16'b0 : tx_q[0] ; +   assign tx_i_1 = chan_txempty[1] ? 16'b0 : tx_i[1] ; +   assign tx_q_1 = chan_txempty[1] ? 16'b0 : tx_q[1] ; +         +   assign tx_q_2 = 16'b0 ; +   assign tx_i_2 = 16'b0 ; +   assign tx_q_3 = 16'b0 ; +   assign tx_i_3 = 16'b0 ; +   assign tx_i_3 = 16'b0 ; +	 +   assign debugbus = {have_space, txclk, WR, WR_final, chan_WR, chan_done,  +                      chan_pkt_waiting[0], chan_pkt_waiting[1], +                      chan_rdreq[0], chan_rdreq[1], chan_txempty[0], chan_txempty[1]}; + +   wire [31:0] usbdata_final; +   wire		WR_final; + +   tx_packer tx_usb_packer +   (.bus_reset(bus_reset), .usbclk(usbclk), .WR_fx2(WR), +    .usbdata(usbdata), .reset(reset), .txclk(txclk), +    .usbdata_final(usbdata_final), .WR_final(WR_final)); +	 +   channel_demux #(NUM_CHAN) channel_demuxer +   (.usbdata_final(usbdata_final), .WR_final(WR_final), +    .reset(reset), .txclk(txclk), .WR_channel(chan_WR), +    .WR_done_channel(chan_done), .ram_data(tx_data_bus)); +	 +   generate for (i = 0 ; i < NUM_CHAN; i = i + 1) +     begin : generate_channel_readers +       assign tx_underrun[i] = chan_underrun[i]; + +       channel_ram tx_data_packet_fifo  +       (.reset(reset), .txclk(txclk), .datain(tx_data_bus), +        .WR(chan_WR[i]), .WR_done(chan_done[i]), +        .have_space(chan_have_space[i]), .dataout(chan_fifodata[i]), +        .packet_waiting(chan_pkt_waiting[i]), .RD(chan_rdreq[i]), +        .RD_done(chan_skip[i])); + +       chan_fifo_reader tx_chan_reader  +       (.reset(reset), .tx_clock(txclk), .tx_strobe(txstrobe), +        .timestamp_clock(timestamp_clock), .samples_format(4'b0),           +        .tx_q(tx_q[i]), .tx_i(tx_i[i]), .underrun(chan_underrun[i]), +        .skip(chan_skip[i]), .rdreq(chan_rdreq[i]), +        .fifodata(chan_fifodata[i]), .pkt_waiting(chan_pkt_waiting[i]), +        .tx_empty(chan_txempty[i]), .rssi(rssi[i]), .debug(debug[i]), +        .threshhold(threshhold), .rssi_wait(rssi_wait));	          +    end +    endgenerate + + +   channel_ram tx_cmd_packet_fifo  +   (.reset(reset), .txclk(txclk), .datain(tx_data_bus), .WR(chan_WR[NUM_CHAN]), +    .WR_done(chan_done[NUM_CHAN]), .have_space(chan_have_space[NUM_CHAN]), +    .dataout(chan_fifodata[NUM_CHAN]), .packet_waiting(chan_pkt_waiting[NUM_CHAN]), +    .RD(chan_rdreq[NUM_CHAN]), .RD_done(chan_skip[NUM_CHAN])); + +   cmd_reader tx_cmd_reader +   (.reset(reset), .txclk(txclk), .timestamp_clock(timestamp_clock), .skip(chan_skip[NUM_CHAN]), +    .rdreq(chan_rdreq[NUM_CHAN]), .fifodata(chan_fifodata[NUM_CHAN]), +    .pkt_waiting(chan_pkt_waiting[NUM_CHAN]), .rx_databus(rx_databus), +    .rx_WR(rx_WR), .rx_WR_done(rx_WR_done), .rx_WR_enabled(rx_WR_enabled), +    .reg_data_in(reg_data_in), .reg_data_out(reg_data_out), .reg_addr(reg_addr), +    .reg_io_enable(reg_io_enable), .debug(debug[NUM_CHAN]), .stop(stop), .stop_time(stop_time)); +				    +endmodule // tx_buffer + diff --git a/fpga/usrp1/inband_lib/tx_packer.v b/fpga/usrp1/inband_lib/tx_packer.v new file mode 100644 index 000000000..2f19b21f3 --- /dev/null +++ b/fpga/usrp1/inband_lib/tx_packer.v @@ -0,0 +1,119 @@ +module tx_packer +   (     //FX2 Side +			input bus_reset,  +			input usbclk,  +			input WR_fx2,  +			input [15:0]usbdata, +			 +			// TX Side +			input reset, +			input txclk, +			output reg [31:0] usbdata_final, +			output reg WR_final); + +	reg [8:0] write_count; + +	/* Fix FX2 bug */ +	always @(posedge usbclk) +	begin +    	if(bus_reset)        // Use bus reset because this is on usbclk +       		write_count <= #1 0; +    	else if(WR_fx2 & ~write_count[8]) +    		write_count <= #1 write_count + 9'd1; +    	else +    		write_count <= #1 WR_fx2 ? write_count : 9'b0; +	end +	 +	reg WR_fx2_fixed; +	reg [15:0]usbdata_fixed; +	 +	always @(posedge usbclk)  +	begin +	   WR_fx2_fixed <= WR_fx2 & ~write_count[8]; +	   usbdata_fixed <= usbdata; +	end + +	/* Used to convert 16 bits bus_data to the 32 bits wide fifo */ +    reg                             word_complete ; +    reg     [15:0]         			usbdata_delayed ; +    reg                             writing ; +	wire	[31:0]					usbdata_packed ;     +	wire							WR_packed ; +    +    always @(posedge usbclk) +    begin +        if (bus_reset) +          begin +            word_complete <= 0 ; +            writing <= 0 ; +          end +        else if (WR_fx2_fixed) +          begin +            writing <= 1 ; +            if (word_complete) +                word_complete <= 0 ; +            else +              begin +                usbdata_delayed <= usbdata_fixed ; +                word_complete <= 1 ; +              end +          end +        else +            writing <= 0 ; +	end +     +	assign usbdata_packed = {usbdata_fixed, usbdata_delayed} ; +    assign WR_packed = word_complete & writing ; + +	/* Make sure data are sync with usbclk */ + 	reg [31:0]usbdata_usbclk; +	reg WR_usbclk;  +     +    always @(posedge usbclk) +    begin +    	if (WR_packed) +    		usbdata_usbclk <= usbdata_packed; +        WR_usbclk <= WR_packed; +    end + +	/* Cross clock boundaries */ +	reg [31:0] usbdata_tx ; +	reg WR_tx; +    reg WR_1; +    reg WR_2; +   +	always @(posedge txclk) usbdata_tx <= usbdata_usbclk; + +    always @(posedge txclk)  +    	if (reset) +    		WR_1 <= 0; +    	else +       		WR_1 <= WR_usbclk; + +    always @(posedge txclk)  +    	if (reset) +       		WR_2 <= 0; +    	else +      		WR_2 <= WR_1; + +	always @(posedge txclk) +	begin +		if (reset) +			WR_tx <= 0; +		else +		   WR_tx <= WR_1 & ~WR_2; +	end +	 +	always @(posedge txclk) +	begin +	   if (reset) +	      WR_final <= 0; +	   else +	   begin +	      WR_final <= WR_tx;  +	      if (WR_tx) +	         usbdata_final <= usbdata_tx; +	   end +	end + +endmodule diff --git a/fpga/usrp1/inband_lib/usb_packet_fifo.v b/fpga/usrp1/inband_lib/usb_packet_fifo.v new file mode 100755 index 000000000..c416e2bdb --- /dev/null +++ b/fpga/usrp1/inband_lib/usb_packet_fifo.v @@ -0,0 +1,112 @@ +module usb_packet_fifo  +  ( input       reset, +    input       clock_in, +    input       clock_out, +    input       [15:0]ram_data_in, +    input       write_enable, +    output  reg [15:0]ram_data_out, +    output  reg pkt_waiting, +    output  reg have_space, +    input       read_enable, +    input       skip_packet          ) ; + +    /* Some parameters for usage later on */ +    parameter DATA_WIDTH = 16 ; +    parameter NUM_PACKETS = 4 ; + +    /* Create the RAM here */ +    reg [DATA_WIDTH-1:0] usb_ram [256*NUM_PACKETS-1:0] ; + +    /* Create the address signals */ +    reg [7-2+NUM_PACKETS:0] usb_ram_ain ; +    reg [7:0] usb_ram_offset ; +    reg [1:0] usb_ram_packet ; + +    wire [7-2+NUM_PACKETS:0] usb_ram_aout ; +    reg isfull; + +    assign usb_ram_aout = {usb_ram_packet,usb_ram_offset} ; +     +    // Check if there is one full packet to process +    always @(usb_ram_ain, usb_ram_aout) +    begin +        if (reset) +            pkt_waiting <= 0; +        else if (usb_ram_ain == usb_ram_aout) +            pkt_waiting <= isfull; +        else if (usb_ram_ain > usb_ram_aout) +            pkt_waiting <= (usb_ram_ain - usb_ram_aout) >= 256; +        else +            pkt_waiting <= (usb_ram_ain + 10'b1111111111 - usb_ram_aout) >= 256; +    end +     +    // Check if there is room +    always @(usb_ram_ain, usb_ram_aout) +    begin +        if (reset) +            have_space <= 1; +        else if (usb_ram_ain == usb_ram_aout) +            have_space <= ~isfull;    +        else if (usb_ram_ain > usb_ram_aout) +            have_space <= (usb_ram_ain - usb_ram_aout) <= 256 * (NUM_PACKETS - 1); +        else +            have_space <= (usb_ram_aout - usb_ram_ain) >= 256; +    end + +    /* RAM Write Address process */ +    always @(posedge clock_in) +    begin +        if( reset ) +            usb_ram_ain <= 0 ; +        else +            if( write_enable )  +              begin +                usb_ram_ain <= usb_ram_ain + 1 ; +                if (usb_ram_ain + 1 == usb_ram_aout) +                   isfull <= 1; +              end +    end + +    /* RAM Writing process */ +    always @(posedge clock_in) +    begin +        if( write_enable )  +          begin +            usb_ram[usb_ram_ain] <= ram_data_in ; +          end +    end + +    /* RAM Read Address process */ +    always @(posedge clock_out) +    begin +        if( reset )  +          begin +            usb_ram_packet <= 0 ; +            usb_ram_offset <= 0 ; +            isfull <= 0; +          end +        else +            if( skip_packet ) +              begin +                usb_ram_packet <= usb_ram_packet + 1 ; +                usb_ram_offset <= 0 ; +              end +            else if(read_enable) +                if( usb_ram_offset == 8'b11111111 ) +                  begin +                    usb_ram_offset <= 0 ; +                    usb_ram_packet <= usb_ram_packet + 1 ; +                  end +                else +                    usb_ram_offset <= usb_ram_offset + 1 ; +            if (usb_ram_ain == usb_ram_aout) +               isfull <= 0;                        +    end + +    /* RAM Reading Process */ +    always @(posedge clock_out) +    begin +        ram_data_out <= usb_ram[usb_ram_aout] ; +    end + +endmodule
\ No newline at end of file | 
