aboutsummaryrefslogtreecommitdiffstats
path: root/tx/convert_30to15_fifo.v
blob: 8ad8727c446a517f380dbb21caabbcd57bb2fc41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
module convert_30to15_fifo(
  input  wire rst,   // reset
  input  wire clk,   // clock input
  input  wire clkx2, // 2x clock input
  input  wire [29:0] datain,   // input data for 2:1 serialisation
  output wire [14:0] dataout); // 5-bit data out

  ////////////////////////////////////////////////////
  // Here we instantiate a 16x10 Dual Port RAM
  // and fill first it with data aligned to
  // clk domain
  ////////////////////////////////////////////////////
  wire  [3:0]   wa;       // RAM read address
  reg   [3:0]   wa_d;     // RAM read address
  wire  [3:0]   ra;       // RAM read address
  reg   [3:0]   ra_d;     // RAM read address
  wire  [29:0]  dataint;  // RAM output

  parameter ADDR0  = 4'b0000;
  parameter ADDR1  = 4'b0001;
  parameter ADDR2  = 4'b0010;
  parameter ADDR3  = 4'b0011;
  parameter ADDR4  = 4'b0100;
  parameter ADDR5  = 4'b0101;
  parameter ADDR6  = 4'b0110;
  parameter ADDR7  = 4'b0111;
  parameter ADDR8  = 4'b1000;
  parameter ADDR9  = 4'b1001;
  parameter ADDR10 = 4'b1010;
  parameter ADDR11 = 4'b1011;
  parameter ADDR12 = 4'b1100;
  parameter ADDR13 = 4'b1101;
  parameter ADDR14 = 4'b1110;
  parameter ADDR15 = 4'b1111;

  always@(wa) begin
    case (wa)
      ADDR0   : wa_d = ADDR1 ;
      ADDR1   : wa_d = ADDR2 ;
      ADDR2   : wa_d = ADDR3 ;
      ADDR3   : wa_d = ADDR4 ;
      ADDR4   : wa_d = ADDR5 ;
      ADDR5   : wa_d = ADDR6 ;
      ADDR6   : wa_d = ADDR7 ;
      ADDR7   : wa_d = ADDR8 ;
      ADDR8   : wa_d = ADDR9 ;
      ADDR9   : wa_d = ADDR10;
      ADDR10  : wa_d = ADDR11;
      ADDR11  : wa_d = ADDR12;
      ADDR12  : wa_d = ADDR13;
      ADDR13  : wa_d = ADDR14;
      ADDR14  : wa_d = ADDR15;
      default : wa_d = ADDR0;
    endcase
  end

  FDC fdc_wa0 (.C(clk),  .D(wa_d[0]), .CLR(rst), .Q(wa[0]));
  FDC fdc_wa1 (.C(clk),  .D(wa_d[1]), .CLR(rst), .Q(wa[1]));
  FDC fdc_wa2 (.C(clk),  .D(wa_d[2]), .CLR(rst), .Q(wa[2]));
  FDC fdc_wa3 (.C(clk),  .D(wa_d[3]), .CLR(rst), .Q(wa[3]));

  //Dual Port fifo to bridge data from clk to clkx2
  DRAM16XN #(.data_width(30))
  fifo_u (
         .DATA_IN(datain),
         .ADDRESS(wa),
         .ADDRESS_DP(ra),
         .WRITE_EN(1'b1),
         .CLK(clk),
         .O_DATA_OUT(),
         .O_DATA_OUT_DP(dataint));

  /////////////////////////////////////////////////////////////////
  // Here starts clk2x domain for fifo read out 
  // FIFO read is set to be once every 2 cycles of clk2x in order
  // to keep up pace with the fifo write speed
  // Also FIFO read reset is delayed a bit in order to avoid
  // underflow.
  /////////////////////////////////////////////////////////////////

  always@(ra) begin
    case (ra)
      ADDR0   : ra_d = ADDR1 ;
      ADDR1   : ra_d = ADDR2 ;
      ADDR2   : ra_d = ADDR3 ;
      ADDR3   : ra_d = ADDR4 ;
      ADDR4   : ra_d = ADDR5 ;
      ADDR5   : ra_d = ADDR6 ;
      ADDR6   : ra_d = ADDR7 ;
      ADDR7   : ra_d = ADDR8 ;
      ADDR8   : ra_d = ADDR9 ;
      ADDR9   : ra_d = ADDR10;
      ADDR10  : ra_d = ADDR11;
      ADDR11  : ra_d = ADDR12;
      ADDR12  : ra_d = ADDR13;
      ADDR13  : ra_d = ADDR14;
      ADDR14  : ra_d = ADDR15;
      default : ra_d = ADDR0;
    endcase
  end

  wire rstsync, rstsync_q, rstp;
  (* ASYNC_REG = "TRUE" *) FDP fdp_rst  (.C(clkx2),  .D(rst), .PRE(rst), .Q(rstsync));

  FD fd_rstsync (.C(clkx2),  .D(rstsync), .Q(rstsync_q));
  FD fd_rstp    (.C(clkx2),  .D(rstsync_q), .Q(rstp));

  wire sync;
  FDR sync_gen (.Q (sync), .C (clkx2), .R(rstp), .D(~sync));

  FDRE fdc_ra0 (.C(clkx2),  .D(ra_d[0]), .R(rstp), .CE(sync), .Q(ra[0]));
  FDRE fdc_ra1 (.C(clkx2),  .D(ra_d[1]), .R(rstp), .CE(sync), .Q(ra[1]));
  FDRE fdc_ra2 (.C(clkx2),  .D(ra_d[2]), .R(rstp), .CE(sync), .Q(ra[2]));
  FDRE fdc_ra3 (.C(clkx2),  .D(ra_d[3]), .R(rstp), .CE(sync), .Q(ra[3]));

  wire [29:0] db;

  FDE fd_db0 (.C(clkx2), .D(dataint[0]),   .CE(sync), .Q(db[0]));
  FDE fd_db1 (.C(clkx2), .D(dataint[1]),   .CE(sync), .Q(db[1]));
  FDE fd_db2 (.C(clkx2), .D(dataint[2]),   .CE(sync), .Q(db[2]));
  FDE fd_db3 (.C(clkx2), .D(dataint[3]),   .CE(sync), .Q(db[3]));
  FDE fd_db4 (.C(clkx2), .D(dataint[4]),   .CE(sync), .Q(db[4]));
  FDE fd_db5 (.C(clkx2), .D(dataint[5]),   .CE(sync), .Q(db[5]));
  FDE fd_db6 (.C(clkx2), .D(dataint[6]),   .CE(sync), .Q(db[6]));
  FDE fd_db7 (.C(clkx2), .D(dataint[7]),   .CE(sync), .Q(db[7]));
  FDE fd_db8 (.C(clkx2), .D(dataint[8]),   .CE(sync), .Q(db[8]));
  FDE fd_db9 (.C(clkx2), .D(dataint[9]),   .CE(sync), .Q(db[9]));
  FDE fd_db10 (.C(clkx2), .D(dataint[10]), .CE(sync), .Q(db[10]));
  FDE fd_db11 (.C(clkx2), .D(dataint[11]), .CE(sync), .Q(db[11]));
  FDE fd_db12 (.C(clkx2), .D(dataint[12]), .CE(sync), .Q(db[12]));
  FDE fd_db13 (.C(clkx2), .D(dataint[13]), .CE(sync), .Q(db[13]));
  FDE fd_db14 (.C(clkx2), .D(dataint[14]), .CE(sync), .Q(db[14]));
  FDE fd_db15 (.C(clkx2), .D(dataint[15]), .CE(sync), .Q(db[15]));
  FDE fd_db16 (.C(clkx2), .D(dataint[16]), .CE(sync), .Q(db[16]));
  FDE fd_db17 (.C(clkx2), .D(dataint[17]), .CE(sync), .Q(db[17]));
  FDE fd_db18 (.C(clkx2), .D(dataint[18]), .CE(sync), .Q(db[18]));
  FDE fd_db19 (.C(clkx2), .D(dataint[19]), .CE(sync), .Q(db[19]));
  FDE fd_db20 (.C(clkx2), .D(dataint[20]), .CE(sync), .Q(db[20]));
  FDE fd_db21 (.C(clkx2), .D(dataint[21]), .CE(sync), .Q(db[21]));
  FDE fd_db22 (.C(clkx2), .D(dataint[22]), .CE(sync), .Q(db[22]));
  FDE fd_db23 (.C(clkx2), .D(dataint[23]), .CE(sync), .Q(db[23]));
  FDE fd_db24 (.C(clkx2), .D(dataint[24]), .CE(sync), .Q(db[24]));
  FDE fd_db25 (.C(clkx2), .D(dataint[25]), .CE(sync), .Q(db[25]));
  FDE fd_db26 (.C(clkx2), .D(dataint[26]), .CE(sync), .Q(db[26]));
  FDE fd_db27 (.C(clkx2), .D(dataint[27]), .CE(sync), .Q(db[27]));
  FDE fd_db28 (.C(clkx2), .D(dataint[28]), .CE(sync), .Q(db[28]));
  FDE fd_db29 (.C(clkx2), .D(dataint[29]), .CE(sync), .Q(db[29]));

  wire [14:0] mux;
  assign mux = (~sync) ? db[14:0] : db[29:15];

  FD fd_out0 (.C(clkx2), .D(mux[0]), .Q(dataout[0]));
  FD fd_out1 (.C(clkx2), .D(mux[1]), .Q(dataout[1]));
  FD fd_out2 (.C(clkx2), .D(mux[2]), .Q(dataout[2]));
  FD fd_out3 (.C(clkx2), .D(mux[3]), .Q(dataout[3]));
  FD fd_out4 (.C(clkx2), .D(mux[4]), .Q(dataout[4]));
  FD fd_out5 (.C(clkx2), .D(mux[5]), .Q(dataout[5]));
  FD fd_out6 (.C(clkx2), .D(mux[6]), .Q(dataout[6]));
  FD fd_out7 (.C(clkx2), .D(mux[7]), .Q(dataout[7]));
  FD fd_out8 (.C(clkx2), .D(mux[8]), .Q(dataout[8]));
  FD fd_out9 (.C(clkx2), .D(mux[9]), .Q(dataout[9]));
  FD fd_out10 (.C(clkx2), .D(mux[10]), .Q(dataout[10]));
  FD fd_out11 (.C(clkx2), .D(mux[11]), .Q(dataout[11]));
  FD fd_out12 (.C(clkx2), .D(mux[12]), .Q(dataout[12]));
  FD fd_out13 (.C(clkx2), .D(mux[13]), .Q(dataout[13]));
  FD fd_out14 (.C(clkx2), .D(mux[14]), .Q(dataout[14]));

endmodule