20 reg [3:0] addr_wr,addr_wr_gray,awg_d1,awg_d2,addr_wr_gray_ret,awgr_d1,addr_wr_ungray,addr_rd;
22 reg [11:0] buffer [0:15];
28 reg [7:0] rxd_d1, rxd_d2;
29 reg rx_dv_d1,rx_er_d1,crs_d1,col_d1, rx_dv_d2,rx_er_d2,crs_d2,col_d2;
33 always @(posedge rx_clk)
34 {col_d1,crs_d1,rx_er_d1,rx_dv_d1,rxd_d1} <= {col,crs,rx_er,rx_dv,rxd};
36 always @(posedge rx_clk)
37 {col_d2,crs_d2,rx_er_d2,rx_dv_d2,rxd_d2} <= {col_d1,crs_d1,rx_er_d1,rx_dv_d1,rxd_d1};
39 always @(posedge rx_clk)
40 buffer[addr_wr] <= {col_d2,crs_d2,rx_er_d2,rx_dv_d1,rxd_d2};
42 always @(posedge rx_clk or posedge rst)
44 else addr_wr <= addr_wr + 1;
46 always @(posedge rx_clk)
48 addr_wr_gray <= {addr_wr[3],^addr_wr[3:2],^addr_wr[2:1],^addr_wr[1:0]};
49 awg_d1 <= addr_wr_gray;
53 always @(posedge tx_clk)
55 addr_wr_gray_ret <= awg_d2;
56 awgr_d1 <= addr_wr_gray_ret;
57 addr_wr_ungray <= {awgr_d1[3],^awgr_d1[3:2],^awgr_d1[3:1],^awgr_d1[3:0]};
60 wire [3:0] addr_delta = addr_rd-addr_wr_ungray;
62 localparam retard = 2'd0;
63 localparam good = 2'd1;
64 localparam advance = 2'd2;
65 localparam wayoff = 2'd3;
69 4'd1, 4'd2, 4'd3, 4'd4, 4'd5 : direction <= retard;
70 4'd15, 4'd14, 4'd13, 4'd12, 4'd11 : direction <= advance;
71 4'd0 : direction <= good;
72 default : direction <= wayoff;
73 endcase // case(addr_delta)
75 always @(posedge tx_clk or posedge rst)
78 else if(rx_dv_ret_adv | rx_dv_ontime)
79 addr_rd <= addr_rd + 1;
82 retard : addr_rd <= addr_rd;
83 advance : addr_rd <= addr_rd + 2;
84 good : addr_rd <= addr_rd + 1;
85 wayoff : addr_rd <= addr_wr_ungray;
86 endcase // case(direction)
88 assign {col_ret,crs_ret,rx_er_ret,rx_dv_ret_adv,rxd_ret} = buffer[addr_rd];
89 always @(posedge tx_clk)
90 rx_dv_ontime <= rx_dv_ret_adv;
92 assign rx_dv_ret = rx_dv_ontime;
93 endmodule // elastic_buffer