commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r7066 - in usrp2/trunk/fpga: . control_lib serdes top/


From: matt
Subject: [Commit-gnuradio] r7066 - in usrp2/trunk/fpga: . control_lib serdes top/u2_basic top/u2_sim
Date: Mon, 3 Dec 2007 21:55:52 -0700 (MST)

Author: matt
Date: 2007-12-03 21:55:52 -0700 (Mon, 03 Dec 2007)
New Revision: 7066

Added:
   usrp2/trunk/fpga/serdes/
   usrp2/trunk/fpga/serdes/serdes.v
   usrp2/trunk/fpga/serdes/serdes_fc_rx.v
   usrp2/trunk/fpga/serdes/serdes_fc_tx.v
   usrp2/trunk/fpga/serdes/serdes_rx.v
   usrp2/trunk/fpga/serdes/serdes_tb.v
   usrp2/trunk/fpga/serdes/serdes_tx.v
Removed:
   usrp2/trunk/fpga/control_lib/serdes_rx.v
   usrp2/trunk/fpga/control_lib/serdes_tb.v
   usrp2/trunk/fpga/control_lib/serdes_tx.v
Modified:
   usrp2/trunk/fpga/top/u2_basic/u2_basic.v
   usrp2/trunk/fpga/top/u2_sim/cmdfile
Log:
serdes in its own directory and upper level block, add flow control


Deleted: usrp2/trunk/fpga/control_lib/serdes_rx.v

Deleted: usrp2/trunk/fpga/control_lib/serdes_tb.v

Deleted: usrp2/trunk/fpga/control_lib/serdes_tx.v

Added: usrp2/trunk/fpga/serdes/serdes.v
===================================================================
--- usrp2/trunk/fpga/serdes/serdes.v                            (rev 0)
+++ usrp2/trunk/fpga/serdes/serdes.v    2007-12-04 04:55:52 UTC (rev 7066)
@@ -0,0 +1,30 @@
+
+// SERDES TX and RX along with all flow control logic
+
+module serdes
+  #(parameter TXFIFOSIZE = 9,
+    parameter RXFIFOSIZE = 9)
+    (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,
+     // 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 );
+
+   
+   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) );
+   
+   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) );
+   
+endmodule // serdes

Added: usrp2/trunk/fpga/serdes/serdes_fc_rx.v
===================================================================
--- usrp2/trunk/fpga/serdes/serdes_fc_rx.v                              (rev 0)
+++ usrp2/trunk/fpga/serdes/serdes_fc_rx.v      2007-12-04 04:55:52 UTC (rev 
7066)
@@ -0,0 +1,62 @@
+
+
+module serdes_fc_rx
+  #(parameter LWMARK = 32,
+    parameter HWMARK = 128)
+    (input clk, input rst,
+     input [15:0] fifo_space, 
+     output reg send_xon,
+     output reg send_xoff,
+     input sent);
+    
+   reg [15:0]    countdown;
+   reg                   send_xon_int, send_xoff_int;
+   
+   always @(posedge clk)
+     if(rst)
+       begin
+         send_xon_int <= 0;
+         send_xoff_int <= 0;
+         countdown <= 0;
+       end
+     else 
+       begin
+         send_xon_int <= 0;
+         send_xoff_int <= 0;
+         if(countdown == 0)
+           if(fifo_space < LWMARK)
+             begin
+                send_xon_int <= 1;
+                countdown <= 250;
+             end
+           else
+             ;
+         else
+           if(fifo_space > HWMARK)
+             begin
+                send_xoff_int <= 1;
+                countdown <= 0;
+             end
+           else
+             countdown <= countdown - 1;
+       end // else: !if(rst)
+
+   // If we are between the high and low water marks, we let the countdown 
expire
+
+   always @(posedge clk)
+     if(rst)
+       send_xon <= 0;
+     else if(send_xon_int)
+       send_xon <= 1;
+     else if(sent)
+       send_xon <= 0;
+
+   always @(posedge clk)
+     if(rst)
+       send_xoff <= 0;
+     else if(send_xoff_int)
+       send_xoff <= 1;
+     else if(sent)
+       send_xoff <= 0;
+   
+endmodule // serdes_fc_rx

Added: usrp2/trunk/fpga/serdes/serdes_fc_tx.v
===================================================================
--- usrp2/trunk/fpga/serdes/serdes_fc_tx.v                              (rev 0)
+++ usrp2/trunk/fpga/serdes/serdes_fc_tx.v      2007-12-04 04:55:52 UTC (rev 
7066)
@@ -0,0 +1,21 @@
+
+
+module serdes_fc_tx
+  (input clk, input rst,
+   input xon_rcvd, input xoff_rcvd, output inhibit_tx);
+
+   reg [15:0] state;
+
+   always @(posedge clk)
+     if(rst)
+       state <= 0;
+     else if(xon_rcvd)
+       state <= 255;
+     else if(xoff_rcvd)
+       state <= 0;
+     else if(state !=0)
+       state <= state - 1;
+
+   assign     inhibit_tx = (state != 0);
+   
+endmodule // serdes_fc_tx

Copied: usrp2/trunk/fpga/serdes/serdes_rx.v (from rev 7065, 
usrp2/trunk/fpga/control_lib/serdes_rx.v)
===================================================================
--- usrp2/trunk/fpga/serdes/serdes_rx.v                         (rev 0)
+++ usrp2/trunk/fpga/serdes/serdes_rx.v 2007-12-04 04:55:52 UTC (rev 7066)
@@ -0,0 +1,263 @@
+
+// SERDES Interface
+
+// LS-Byte is sent first, MS-Byte is second
+// Invalid K Codes
+//  K0.0  000-00000  Error detected
+//  K31.7 111-11111  Loss of input signal
+
+// Valid K Codes
+//  K28.0 000-11100
+//  K28.1 001-11100  Alternate COMMA?
+//  K28.2 010-11100
+//  K28.3 011-11100
+//  K28.4 100-11100
+//  K28.5 101-11100  Standard COMMA?
+//  K28.6 110-11100
+//  K28.7 111-11100  Bad COMMA?
+//  K23.7 111-10111
+//  K27.7 111-11011
+//  K29.7 111-11101
+//  K30.7 111-11110
+
+module serdes_rx
+  #(parameter FIFOSIZE = 9)
+    (input clk,
+     input rst,
+     
+     // RX HW Interface
+     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
+     );
+   
+   localparam K_COMMA = 8'b101_11100;     // 0xBC K28.5
+   localparam K_IDLE = 8'b001_11100;      // 0x3C K28.1
+   localparam K_PKT_START = 8'b110_11100; // 0xDC K28.6
+   localparam K_PKT_END = 8'b100_11100;   // 0x9C K28.4
+   localparam K_LOS = 8'b111_11111;       // 0xFF K31.7
+   localparam K_ERROR = 8'b000_00000;     // 0x00 K00.0
+   
+   localparam IDLE = 3'd0;
+   localparam FIRSTLINE1 = 3'd1;
+   localparam FIRSTLINE2 = 3'd2;
+   localparam PKT1 = 3'd3;
+   localparam PKT2 = 3'd4;
+   localparam CRC_CHECK = 3'd5;
+   localparam ERROR = 3'd6;
+   localparam DONE = 3'd7;
+   
+   wire [17:0] even_data;
+   reg [17:0]  odd_data;
+   wire [17:0] chosen_data;
+   reg                odd;
+   
+   reg [31:0]  line_i;
+   reg                sop_i, eop_i, error_i;
+   wire        error_o, sop_o, eop_o, write, read, empty, full;
+   reg [15:0]  halfline;
+   reg                data_valid, phase;
+   reg [8:0]   holder;
+   wire [31:0] line_o;
+   
+   reg [2:0]   state;
+
+   reg [15:0]  CRC;
+   wire [15:0] nextCRC;
+   reg                write_d;
+   
+   ss_rcvr #(.WIDTH(18)) ss_rcvr
+     (.rxclk(ser_rx_clk),.sysclk(clk),.rst(rst),
+      .data_in({ser_rkmsb,ser_rklsb,ser_r}),.data_out(even_data),
+      .clock_present());
+   
+   always @(posedge clk)
+     if(rst)
+       holder <= 9'd0;
+     else
+       holder <= {even_data[17],even_data[15:8]};
+   
+   always @(posedge clk)
+     if(rst)
+       odd_data <= 18'd0;
+     else
+       odd_data <= {even_data[16],holder[8],even_data[7:0],holder[7:0]};
+   
+   assign      chosen_data = odd ? odd_data : even_data;
+
+/*   
+   always @(posedge clk)
+     if(phase == 1)
+       line_i = {chosen_data[15:0], halfline};
+ */
+
+   always @(posedge clk)
+     if(rst) sop_i <= 0;
+     else if(state == FIRSTLINE1) sop_i <= 1;
+     else if(write_d) sop_i <= 0;
+   
+   reg                write_pre;
+   always @(posedge clk)
+     if(rst)
+       begin
+         state <= IDLE;
+         odd <= 0;
+         halfline <= 0;
+         line_i <= 0;
+         eop_i <= 0;
+         error_i <= 0;
+         write_pre <= 0;
+       end
+     else
+       case(state)
+        IDLE :
+          begin
+             error_i <= 0;
+             write_pre <= 0;
+             if(even_data == {2'b11,K_PKT_START,K_PKT_START})
+               begin
+                  state <= FIRSTLINE1;
+                  odd <= 0;
+               end
+             else if(odd_data == {2'b11,K_PKT_START,K_PKT_START})
+               begin
+                  state <= FIRSTLINE1;
+                  odd <= 1;
+               end
+          end
+
+        FIRSTLINE1 :
+          if(chosen_data[17:16] == 0)
+            begin
+               halfline <= chosen_data[15:0];
+               state <= FIRSTLINE2;
+            end
+          else if(chosen_data == {2'b11,K_COMMA,K_COMMA})
+            ;  // Flow Controlled, so wait here and do nothing
+          else
+            state <= ERROR;
+
+        FIRSTLINE2 :
+          if(chosen_data[17:16] == 0)
+            begin
+               line_i <= {chosen_data[15:0],halfline};
+               if(full)  // No space to write to!  Should have been avoided by 
flow control
+                 state <= ERROR;
+               else
+                 begin
+                    state <= PKT1;
+                    write_pre <= 1;
+                 end
+            end // if (chosen_data[17:16] == 0)
+          else if(chosen_data == {2'b11,K_COMMA,K_COMMA})
+            ;  // Flow Controlled, so wait here and do nothing
+          else
+            state <= ERROR;
+        
+        PKT1 :
+          begin
+             write_pre <= 0;
+             if(chosen_data[17:16] == 0)
+               begin
+                  halfline <= chosen_data[15:0];
+                  state <= PKT2;
+               end
+             else if(chosen_data == {2'b11,K_COMMA,K_COMMA})
+               ;  // Flow Controlled
+             else if(chosen_data == {2'b11,K_PKT_END,K_PKT_END})
+               state <= CRC_CHECK;
+             else
+               state <= ERROR;
+          end // case: PKT1
+        
+        PKT2 :
+          if(chosen_data[17:16] == 0)
+            begin
+               line_i <= {1'b0,1'b0,1'b0,chosen_data[15:0],halfline};
+               if(full)  // No space to write to!
+                 state <= ERROR;
+               else
+                 begin
+                    state <= PKT1;
+                    write_pre <= 1;
+                 end
+            end // if (chosen_data[17:16] == 0)
+          else if(chosen_data == {2'b11,K_COMMA,K_COMMA})
+            ;  // Flow Controlled
+          else
+            state <= ERROR;
+          
+        CRC_CHECK :
+          if(chosen_data[17:0] == {2'b00,CRC})
+            begin
+               state <= DONE;
+               eop_i <= 1;
+            end
+          else
+            state <= ERROR;
+        
+        ERROR :
+          begin
+             error_i <= 1;
+             if(~full)
+               state <= IDLE;
+          end
+        DONE :
+          begin
+             state <= IDLE;
+             eop_i <= 0;
+          end
+             
+       endcase // case(state)
+   
+   
+   always @(posedge clk)
+     if(rst)
+       CRC <= 16'hFFFF;
+     else if(state == IDLE)
+       CRC <= 16'hFFFF;
+     else if(chosen_data[17:16] == 2'b00)
+       CRC <= nextCRC;
+
+   CRC16_D16 crc_blk(chosen_data[15:0],CRC,nextCRC);
+
+   always @(posedge clk)
+     if(rst) write_d <= 0;
+     else write_d <= write_pre;
+
+   // Internal FIFO, size 9 is 2K, size 10 is 4K Bytes
+   assign write = eop_i | (error_i & ~full) | (write_d & (state != CRC_CHECK));
+   cascadefifo2 #(.WIDTH(35),.SIZE(FIFOSIZE)) serdes_rx_fifo
+     (.clk(clk),.rst(rst),
+      .datain({error_i,sop_i,eop_i,line_i}), .write(write), .full(full),
+      .dataout({error_o,sop_o,eop_o,line_o}), .read(read), .empty(empty) );
+   
+   // Internal FIFO to Buffer interface
+   reg                xfer_active;
+
+   always @(posedge clk)
+     if(rst)
+       xfer_active <= 0;
+     else if(~empty & (eop_o | wr_full_i))
+       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 & error_o;
+
+   assign      wr_dat_o = line_o;
+   
+endmodule // serdes_rx

Copied: usrp2/trunk/fpga/serdes/serdes_tb.v (from rev 7065, 
usrp2/trunk/fpga/control_lib/serdes_tb.v)
===================================================================
--- usrp2/trunk/fpga/serdes/serdes_tb.v                         (rev 0)
+++ usrp2/trunk/fpga/serdes/serdes_tb.v 2007-12-04 04:55:52 UTC (rev 7066)
@@ -0,0 +1,328 @@
+
+// FIXME need to add flow control
+
+module serdes_tb();
+   
+   reg clk, rst;
+   wire ser_rx_clk, ser_tx_clk;
+   wire ser_rklsb, ser_rkmsb, ser_tklsb, ser_tkmsb;
+   wire [15:0] ser_r, ser_t;
+   
+   initial clk = 0;
+   initial rst = 1;
+   initial #1000 rst = 0;
+   always #100 clk = ~clk;
+   
+   // Wishbone
+   reg [31:0]  wb_dat_i;
+   wire [31:0] wb_dat_o_rx, wb_dat_o_tx;
+   reg                wb_we, wb_en_rx, wb_en_tx;
+   reg [8:0]   wb_adr;
+
+   // Buffer Control
+   reg                go, clear, read, write;
+   reg [3:0]   buf_num;
+   wire [31:0] ctrl_word = 
{buf_num,3'b0,clear,write,read,step,lastline,firstline};
+   reg [8:0]   firstline = 0, lastline = 0;
+   reg [3:0]   step = 1;
+   reg                first_tx = 1, first_rx = 1;  // for verif
+   
+   // TX Side
+   reg                wb_we_tx;
+   wire        en_tx, we_tx;
+   wire [8:0]  addr_tx;
+   wire [31:0] f2r_tx, r2f_tx;
+   wire [31:0] data_tx;
+   wire        read_tx, done_tx, error_tx, sop_tx, eop_tx;
+   
+   wire        fdone_tx, ferror_tx;
+   
+   reg                even;
+   reg                channel_error = 0;
+   
+   serdes_tx 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(data_tx),.rd_read_o(read_tx),.rd_done_o(done_tx),
+      .rd_error_o(error_tx),.rd_sop_i(sop_tx),.rd_eop_i(eop_tx) );
+   
+   ram_2port #(.DWIDTH(32),.AWIDTH(9))
+     
ram_tx(.clka(clk),.ena(wb_en_tx),.wea(wb_we_tx),.addra(wb_adr),.dia(wb_dat_i),.doa(wb_dat_o_tx),
+            
.clkb(clk),.enb(en_tx),.web(we_tx),.addrb(addr_tx),.dib(f2r_tx),.dob(r2f_tx));
+   
+   buffer_int #(.BUFF_NUM(1)) buffer_int_tx
+     (.clk(clk),.rst(rst),
+      .ctrl_word(ctrl_word),.go(go),
+      .done(fdone_tx),.error(ferror_tx),
+      
+      
.en_o(en_tx),.we_o(we_tx),.addr_o(addr_tx),.dat_to_buf(f2r_tx),.dat_from_buf(r2f_tx),
+      
+      .wr_dat_i(0),.wr_write_i(0),.wr_done_i(0),
+      .wr_error_i(0),.wr_ready_o(),.wr_full_o(),
+      
+      .rd_dat_o(data_tx),.rd_read_i(read_tx),.rd_done_i(done_tx),
+      .rd_error_i(error_tx),.rd_sop_o(sop_tx),.rd_eop_o(eop_tx) );
+
+
+   // RX Side
+   reg                wb_we_rx;
+   wire        en_rx, we_rx;
+   wire [8:0]  addr_rx;
+   wire [31:0] f2r_rx, r2f_rx;
+   wire [31:0] data_rx;
+   wire        write_rx, done_rx, error_rx, ready_rx, empty_rx;
+   
+   wire        fdone_rx, ferror_rx;
+   
+   serdes_rx 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(data_rx),.wr_write_o(write_rx),.wr_done_o(done_rx),
+      .wr_error_o(error_rx),.wr_ready_i(ready_rx),.wr_full_i(full_rx) );
+
+   ram_2port #(.DWIDTH(32),.AWIDTH(9))
+     
ram_rx(.clka(clk),.ena(wb_en_rx),.wea(wb_we_rx),.addra(wb_adr),.dia(wb_dat_i),.doa(wb_dat_o_rx),
+            
.clkb(clk),.enb(en_rx),.web(we_rx),.addrb(addr_rx),.dib(f2r_rx),.dob(r2f_rx) );
+   
+   buffer_int #(.BUFF_NUM(0)) buffer_int_rx
+     (.clk(clk),.rst(rst),
+      .ctrl_word(ctrl_word),.go(go),
+      .done(fdone_rx),.error(ferror_rx),
+      
+      
.en_o(en_rx),.we_o(we_rx),.addr_o(addr_rx),.dat_to_buf(f2r_rx),.dat_from_buf(r2f_rx),
+      
+      .wr_dat_i(data_rx),.wr_write_i(write_rx),.wr_done_i(done_rx),
+      .wr_error_i(error_rx),.wr_ready_o(ready_rx),.wr_full_o(full_rx),
+      
+      .rd_dat_o(),.rd_read_i(0),.rd_done_i(0),
+      .rd_error_i(0),.rd_sop_o(),.rd_eop_o() );
+
+   // Simulate the connection
+   serdes_model serdes_model
+     (.ser_tx_clk(ser_tx_clk), .ser_tkmsb(ser_tkmsb), .ser_tklsb(ser_tklsb), 
.ser_t(ser_t),
+      .ser_rx_clk(ser_rx_clk), .ser_rkmsb(ser_rkmsb), .ser_rklsb(ser_rklsb), 
.ser_r(ser_r),
+      .even(even), .error(channel_error) );
+   
+   initial begin
+      wb_en_rx <= 0;
+      wb_en_tx <=0;
+      wb_we_tx <= 0;
+      wb_we_rx <= 0;
+      wb_adr <= 0;
+      wb_dat_i <= 0;
+      go <= 0;
+      even <= 0;
+      @(negedge rst);
+      @(posedge clk);
+      FillTXRAM;
+      ClearRXRAM;
+      ResetBuffer(0);
+      ResetBuffer(1);
+
+      // receive a full buffer
+      ReceiveSERDES(0,10);
+      SendSERDES(0,10);
+
+      // Receive a partial buffer
+      SendSERDES(11,20);
+      ReceiveSERDES(11,50);
+
+      // Receive too many for buffer
+      SendSERDES(21,100);
+      ReceiveSERDES(21,30);
+
+      // Send 3 packets, then wait to receive them, so they stack up in the rx 
fifo
+      SendSERDES(31,40);
+      SendSERDES(41,50);
+      SendSERDES(51,60);
+      repeat (10)
+       @(posedge clk);
+      ReceiveSERDES(31,40);
+      ReceiveSERDES(41,50);
+      repeat (1000)
+       @(posedge clk);
+      ReceiveSERDES(51,60);
+
+      // Overfill the FIFO, should get an error on 3rd packet
+      SendSERDES(1,400);
+      SendSERDES(1,400);
+      
+      
+      WaitForTX;
+      //WaitForRX;
+      
+
+      repeat(1000)
+       @(posedge clk);
+      ReceiveSERDES(101,500);
+      ReceiveSERDES(101,500);
+      ReadRAM(80);
+      $finish;
+   end // initial begin
+
+   always @(posedge clk)
+     if(write_rx)
+       $display("SERDES RX, FIFO WRITE %x, FIFO RDY %d, FIFO FULL %d",data_rx, 
ready_rx, full_rx);
+   
+   always @(posedge clk)
+     if(read_tx)
+       $display("SERDES TX, FIFO READ %x, SOP %d, EOP %d",data_tx, sop_tx, 
eop_tx);
+   
+   initial begin
+      $dumpfile("serdes_tb.vcd");
+      $dumpvars(0,serdes_tb);
+   end
+
+   initial #10000000 $finish;
+
+   initial #259300 channel_error <= 1;
+   initial #259500 channel_error <= 0;
+   
+   task FillTXRAM;
+      begin
+        wb_adr <= 0;
+        wb_dat_i <= 32'h10802000;
+        wb_we_tx <= 1;
+        wb_en_tx <= 1;
+        @(posedge clk);
+        repeat(511) begin
+           wb_dat_i <= wb_dat_i + 32'h00010001;
+           wb_adr <= wb_adr + 1;
+           @(posedge clk);
+        end // repeat (511)
+        wb_we_tx <= 0;
+        wb_en_tx <= 0;
+        @(posedge clk);
+        $display("Done entering Data into TX RAM\n");
+      end
+   endtask // FillTXRAM
+   
+   task ClearRXRAM;
+      begin
+        wb_adr <= 0;
+        wb_dat_i <= 0;
+        wb_we_rx <= 1;
+        wb_en_rx <= 1;
+        wb_dat_i <= 0;
+        @(posedge clk);
+        repeat(511) begin
+           wb_adr <= wb_adr + 1;
+           @(posedge clk);
+        end // repeat (511)
+        wb_we_rx <= 0;
+        wb_en_rx <= 0;
+        @(posedge clk);
+        $display("Done clearing RX RAM\n");
+      end
+   endtask // FillRAM
+   
+   task ReadRAM;
+      input [8:0] lastline;
+      begin
+        wb_en_rx <= 1;
+        wb_adr <= 0;
+        @(posedge clk);
+        @(posedge clk);
+        repeat(lastline) begin
+           $display("ADDR: %h  DATA %h", wb_adr, wb_dat_o_rx);
+           wb_adr <= wb_adr + 1;
+           @(posedge clk);
+           @(posedge clk);
+        end // repeat (511)
+        $display("ADDR: %h  DATA %h", wb_adr, wb_dat_o_rx);
+        wb_en_rx <= 0;
+        @(posedge clk);
+        $display("Done reading out RX RAM\n");
+      end
+   endtask // FillRAM
+   
+   task ResetBuffer;
+      input [3:0] buffer_num;
+      begin
+        buf_num <= buffer_num;
+        clear <= 1; read <= 0; write <= 0;
+        go <= 1;
+        @(posedge clk);
+        go <= 0;
+        @(posedge clk);
+        $display("Buffer Reset");
+      end
+   endtask // ClearBuffer
+   
+   task SetBufferWrite;
+      input [3:0] buffer_num;
+      input [8:0] start;
+      input [8:0] stop;
+      begin
+        buf_num <= buffer_num;
+        clear <= 0; read <= 0; write <= 1;
+        firstline <= start;
+        lastline <= stop;
+        go <= 1;
+        @(posedge clk);
+        go <= 0;
+        @(posedge clk);
+        $display("Buffer Set for Write");
+      end
+   endtask // SetBufferWrite
+   
+   task SetBufferRead;
+      input [3:0] buffer_num;
+      input [8:0] start;
+      input [8:0] stop;
+      begin
+        buf_num <= buffer_num;
+        clear <= 0; read <= 1; write <= 0;
+        firstline <= start;
+        lastline <= stop;
+        go <= 1;
+        @(posedge clk);
+        go <= 0;
+        @(posedge clk);
+        $display("Buffer Set for Read");
+      end
+   endtask // SetBufferRead
+
+   task WaitForTX;
+      begin
+        while (!(fdone_tx | ferror_tx))
+          @(posedge clk);
+      end
+   endtask // WaitForTX
+   
+   task WaitForRX;
+      begin
+        while (!(fdone_rx | ferror_rx))
+          @(posedge clk);
+      end
+   endtask // WaitForRX
+   
+   task SendSERDES;
+      input [8:0] start;
+      input [8:0] stop;
+      begin
+        if(~first_tx)
+          WaitForTX;
+        else
+          first_tx <= 0;
+        ResetBuffer(1);
+        SetBufferRead(1,start,stop);
+        $display("Here");
+      end
+   endtask // SendSERDES
+   
+   task ReceiveSERDES;
+      input [8:0] start;
+      input [8:0] stop;
+      begin
+        if(~first_rx)
+          WaitForRX;
+        else
+          first_rx <= 0;
+        ResetBuffer(0);
+        SetBufferWrite(0,start,stop);
+        $display("Here2");
+      end
+   endtask // ReceiveSERDES
+   
+endmodule // serdes_tb

Copied: usrp2/trunk/fpga/serdes/serdes_tx.v (from rev 7065, 
usrp2/trunk/fpga/control_lib/serdes_tx.v)
===================================================================
--- usrp2/trunk/fpga/serdes/serdes_tx.v                         (rev 0)
+++ usrp2/trunk/fpga/serdes/serdes_tx.v 2007-12-04 04:55:52 UTC (rev 7066)
@@ -0,0 +1,167 @@
+
+// SERDES Interface
+
+// LS-Byte is sent first, MS-Byte is second
+// Invalid K Codes
+//  K0.0  000-00000  Error detected
+//  K31.7 111-11111  Loss of input signal
+
+// Valid K Codes
+//  K28.0 000-11100
+//  K28.1 001-11100  Alternate COMMA?
+//  K28.2 010-11100
+//  K28.3 011-11100
+//  K28.4 100-11100
+//  K28.5 101-11100  Standard COMMA?
+//  K28.6 110-11100
+//  K28.7 111-11100  Bad COMMA?
+//  K23.7 111-10111
+//  K27.7 111-11011
+//  K29.7 111-11101
+//  K30.7 111-11110
+
+module serdes_tx
+  #(parameter FIFOSIZE = 9)
+    (input clk,
+     input rst,
+     
+     // TX HW Interface
+     output ser_tx_clk,
+     output reg [15:0] ser_t,
+     output reg ser_tklsb,
+     output reg ser_tkmsb,
+     
+     // 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
+     );
+   
+   localparam K_COMMA = 8'b101_11100;     // 0xBC K28.5
+   localparam K_IDLE = 8'b001_11100;      // 0x3C K28.1
+   localparam K_PKT_START = 8'b110_11100; // 0xDC K28.6
+   localparam K_PKT_END = 8'b100_11100;   // 0x9C K28.4
+   localparam K_LOS = 8'b111_11111;       // 0xFF K31.7
+   localparam K_ERROR = 8'b000_00000;     // 0x00 K00.0
+   
+   assign     ser_tx_clk = clk;
+   
+   localparam IDLE = 3'd0;
+   localparam RUN1 = 3'd1;
+   localparam RUN2 = 3'd2;
+   localparam DONE = 3'd3;
+   localparam SENDCRC = 3'd4;
+   localparam WAIT = 3'd5;
+   
+   reg [2:0]  state;
+   
+   reg [15:0] CRC;
+   wire [15:0] nextCRC;
+   
+   
+   // Internal FIFO, size 9 is 2K, size 10 is 4K bytes
+   wire        sop_o, eop_o, write, full, read, empty;
+   wire [31:0] data_o;
+   reg                xfer_active;
+   
+   cascadefifo #(.WIDTH(34),.SIZE(FIFOSIZE)) serdes_tx_fifo
+     (.clk(clk),.rst(rst),
+      .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) );
+   
+   // 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
+   
+   reg [15:0]  second_word;
+   reg [33:0]  pipeline;
+   
+   wire        throttle_me = 0;   // Flow control here
+   
+   assign      read = (state==RUN2) | ((state==IDLE) & ~empty & ~sop_o);  
+   // 2nd half of above probably not necessary.  Just in case we get junk 
between packets
+   
+   always @(posedge clk)
+     if(rst)
+       begin
+         state <= IDLE;
+         {ser_tkmsb,ser_tklsb,ser_t} <= {2'b11,K_COMMA,K_COMMA};
+       end
+     else
+       case(state)
+        IDLE :
+          begin
+             if(sop_o & ~empty & ~throttle_me)
+               begin
+                  {ser_tkmsb,ser_tklsb,ser_t} <= 
{2'b11,K_PKT_START,K_PKT_START};
+                  state <= RUN1;
+               end
+             else
+               {ser_tkmsb,ser_tklsb,ser_t} <= {2'b11,K_COMMA,K_COMMA};
+          end
+        RUN1 :
+          begin
+             if(empty | throttle_me)
+               {ser_tkmsb,ser_tklsb,ser_t} <= {2'b11,K_COMMA,K_COMMA};
+             else
+               begin
+                  {ser_tkmsb,ser_tklsb,ser_t} <= {2'b00,data_o[15:0]};
+                  state <= RUN2;
+               end
+          end
+        RUN2 :
+          begin
+             {ser_tkmsb,ser_tklsb,ser_t} <= {2'b00,data_o[31:16]};
+             if(eop_o)
+               state <= DONE;
+             else
+               state <= RUN1;
+          end
+        DONE :
+          begin
+             {ser_tkmsb,ser_tklsb,ser_t} <= {2'b11,K_PKT_END,K_PKT_END};
+             state <= SENDCRC;
+          end
+        SENDCRC :
+          begin
+             {ser_tkmsb,ser_tklsb,ser_t} <= {2'b00,CRC};
+             state <= WAIT;
+          end
+        WAIT :
+          begin
+             {ser_tkmsb,ser_tklsb,ser_t} <= {2'b11,K_COMMA,K_COMMA};
+             state <= IDLE;
+          end
+        default
+          state <= IDLE;
+       endcase // case(state)
+   
+   always @(posedge clk)
+     if(rst)
+       CRC <= 16'hFFFF;
+     else if(state == IDLE)
+       CRC <= 16'hFFFF;
+     else if( (~empty & ~throttle_me & (state==RUN1)) || (state==RUN2) )
+       CRC <= nextCRC;
+   
+   CRC16_D16 crc_blk( (state==RUN1) ? data_o[15:0] : data_o[31:16], CRC, 
nextCRC);
+   
+endmodule // serdes_tx
+

Modified: usrp2/trunk/fpga/top/u2_basic/u2_basic.v
===================================================================
--- usrp2/trunk/fpga/top/u2_basic/u2_basic.v    2007-12-03 21:34:01 UTC (rev 
7065)
+++ usrp2/trunk/fpga/top/u2_basic/u2_basic.v    2007-12-04 04:55:52 UTC (rev 
7066)
@@ -535,20 +535,14 @@
    // 
///////////////////////////////////////////////////////////////////////////////////
    // SERDES
 
-   serdes_tx #(.FIFOSIZE(9)) serdes_tx
+   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)
-      );
-   
-   serdes_rx #(.FIFOSIZE(9)) serdes_rx
-     (.clk(dsp_clk),.rst(dsp_rst),
+      .rd_sop_i(rd0_sop),.rd_eop_i(rd0_eop),
       
.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_ready_i(wr0_ready),.wr_full_i(wr0_full) );
   
    // 
/////////////////////////////////////////////////////////////////////////////////////////
    // Debug Pins

Modified: usrp2/trunk/fpga/top/u2_sim/cmdfile
===================================================================
--- usrp2/trunk/fpga/top/u2_sim/cmdfile 2007-12-03 21:34:01 UTC (rev 7065)
+++ usrp2/trunk/fpga/top/u2_sim/cmdfile 2007-12-04 04:55:52 UTC (rev 7066)
@@ -2,6 +2,7 @@
 -y .
 -y ../u2_basic
 -y ../../control_lib
+-y ../../serdes
 -y ../../sdr_lib
 
 # Models





reply via email to

[Prev in Thread] Current Thread [Next in Thread]