commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r5838 - gnuradio/branches/developers/matt/u2f/control_


From: matt
Subject: [Commit-gnuradio] r5838 - gnuradio/branches/developers/matt/u2f/control_lib
Date: Mon, 25 Jun 2007 20:48:51 -0600 (MDT)

Author: matt
Date: 2007-06-25 20:48:51 -0600 (Mon, 25 Jun 2007)
New Revision: 5838

Added:
   gnuradio/branches/developers/matt/u2f/control_lib/ss_rcvr.v
Log:
first cut at a mini-FIFO to handle the source-synchronous nature of the rx 
serdes


Added: gnuradio/branches/developers/matt/u2f/control_lib/ss_rcvr.v
===================================================================
--- gnuradio/branches/developers/matt/u2f/control_lib/ss_rcvr.v                 
        (rev 0)
+++ gnuradio/branches/developers/matt/u2f/control_lib/ss_rcvr.v 2007-06-26 
02:48:51 UTC (rev 5838)
@@ -0,0 +1,81 @@
+
+
+// Source-synchronous receiver
+// Assumes both clocks are at the same rate
+// Relative clock phase is
+//    unknown
+//    variable
+//    bounded
+// The output will come several cycles later than the input
+
+// This should synthesize efficiently in Xilinx distributed ram cells,
+//   which is why we use a buffer depth of 16
+
+// FIXME Async reset on rxclk side?
+
+module ss_rcvr
+  #(parameter WIDTH=16)
+    (input rxclk,
+     input sysclk,
+     input rst,
+     
+     input [15:0] data_in,
+     output [15:0] data_out,
+     output reg clock_present);
+   
+   wire [3:0] rd_addr, wr_addr;
+
+   // Distributed RAM
+   reg [WIDTH-1:0] buffer [0:15];
+   always @(posedge rxclk)
+     buffer[wr_addr] <= data_in;
+   
+   assign         data_out = buffer[rd_addr];
+   
+   // Write address generation
+   reg [3:0]      wr_counter;
+   always @(posedge rxclk or posedge rst)
+     if (rst)
+       wr_counter <= 0;
+     else
+       wr_counter <= wr_counter + 1;
+   
+   assign         wr_addr = {wr_counter[3], ^wr_counter[3:2], 
^wr_counter[2:1], ^wr_counter[1:0]};
+   
+   // Read Address generation
+   wire [3:0]     wr_ctr_sys, diff, abs_diff;
+   reg [3:0]      wr_addr_sys_d1, wr_addr_sys_d2;
+   
+   assign         rd_addr = {rd_counter[3], ^rd_counter[3:2], 
^rd_counter[2:1], ^rd_counter[1:0]};
+   
+   always @(posedge sysclk)
+     wr_addr_sys_d1 <= wr_addr;
+   
+   always @(posedge sysclk)
+     wr_addr_sys_d2 <= wr_addr_sys_d1;
+   
+   assign         wr_ctr_sys = 
{wr_addr_sys_d2[3],^wr_addr_sys_d2[3:2],^wr_addr_sys_d2[3:1],^wr_addr_sys_d2[3:0]};
+   
+   assign         diff = wr_counter_sys - rd_counter;
+   assign         abs_diff = diff[3] ? (~diff+1) : diff;
+   
+   reg [3:0]      rd_counter;
+   always @(posedge sysclk)
+     if(rst)
+       begin
+         clock_present <= 0;
+         rd_counter <= 0;
+       end
+     else 
+       if(~clock_present)
+        if(abs_diff > 5)
+          clock_present <= 1;
+        else
+          ;
+       else
+        if(abs_diff<3)
+          clock_present <= 0;
+        else
+          rd_counter <= rd_counter + 1;
+
+endmodule // ss_rcvr





reply via email to

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