x393  1.0
FPGAcodeforElphelNC393camera
ahci_dma_rd_stuff.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  input rst, // sync reset
43  input clk, // single clock
44  input din_av, // input data available
45  input din_avm_w,// >1 word of data available (early)
46  input din_avm, // >1 word of data available (registered din_avm_w)
47  input flushing, // output partial dword if available (should be ? cycles after last _re/ with data?)
48  input [31:0] din, // 32-bit input dfata
49  input [1:0] dm, // data mask showing which (if any) words in input dword are valid
50  output din_re, // read input data
51  output flushed, // flush (end of last PRD is finished - data left module)
52  output reg [31:0] dout, // output 32-bit data
53  output dout_vld, // output data valid
54  input dout_re, // consumer reads output data (should be AND-ed with dout_vld)
55  output last_DW
56 );
57  reg [15:0] hr; // holds 16-bit data from previous din_re if not consumed
58  reg hr_full;
59  reg [1:0] dout_vld_r;
61  reg din_re_r;
62  wire [1:0] dav_in = {2{din_av_safe_r}} & dm;
63  wire [1:0] drd_in = {2{din_re}} & dm;
64 
65  wire [15:0] debug_din_low = din[15: 0];
66  wire [15:0] debug_din_high = din[31:16];
67  wire [15:0] debug_dout_low = dout[15: 0];
68  wire [15:0] debug_dout_high = dout[31:16];
69 
70 // wire empty_in = din_av_safe_r && !(|dm);
71 // wire two_words_avail = &dav_in || (|dav_in && hr_full);
73  wire [1:0] next_or_empty = {2{dout_re}} | ~dout_vld_r;
74 /// assign din_re = (din_av_safe_r && !(|dm)) || ((!dout_vld_r || dout_re) && (two_words_avail)) ; // flush
75 
76 // ---------------
77 
78  wire room_for2 = dout_re || (!(&dout_vld_r) && !hr_full) || !(|dout_vld_r);
79  wire room_for1 = dout_re || !hr_full || !(&dout_vld_r);
80  reg slow_down; // first time fifo almost empty
81  reg slow_dav; // enable dout_vld waiting after each read out not to miss last DWORD
82  reg last_DW_r;
85  reg [1:0] no_new_data_r;
86 
87 
88 
89  assign din_re = din_av_safe_r && (!(|dm) || room_for2 || (room_for1 && !(&dm)));
90 
91 /// assign dout_vld = (&dout_vld_r) || ((|dout_vld_r) && flushing);
92  assign dout_vld = (!slow_down && (&dout_vld_r)) || slow_dav;
93 
94  assign last_DW = last_DW_r;
95  assign flushed = last_DW_r && dout_re;
96  assign no_new_data_w = !din_av && !hr_full;
97 // assign flushed =
98 
99  always @ (posedge clk) begin
100  din_re_r <= din_re;
101 
102  if (rst) din_av_safe_r <= 0;
103  else din_av_safe_r <= din_av && (din_avm || (!din_re && !din_re_r));
104 
105  // set low word of the OR
106  if (rst) dout_vld_r[0] <= 0;
107  else if (next_or_empty[0]) dout_vld_r[0] <= hr_full || (din_re && (|dm));
108 
109  if (next_or_empty[0]) begin
110  if (hr_full) dout[15: 0] <= hr;
111  else if (din_re) begin
112  if (dm[0]) dout[15: 0] <= din[15: 0];
113  else if (dm[1]) dout[15: 0] <= din[31:16];
114  end
115  end
116 
117  // set high word of the OR
118  if (rst) dout_vld_r[1] <= 0;
119  else if (next_or_empty[1]) dout_vld_r[1] <= next_or_empty[0]?
120  (din_re && ((hr_full &&(|dm)) || (&dm))) :
121  (hr_full || (din_re && (|dm)));
122 
123  if (next_or_empty[1]) begin
124  if (next_or_empty[0]) begin
125  if (din_re) begin
126  if (hr_full && dm[0]) dout[31:16] <= din[15: 0];
127  else if (dm[1] && (!hr_full || dm[0])) dout[31:16] <= din[31:16];
128  end
129  end else begin
130  if (hr_full) dout[31:16] <= hr;
131  else if (din_re) begin
132  if (dm[0]) dout[31:16] <= din[15: 0];
133  else if (dm[1]) dout[31:16] <= din[31:16];
134  end
135  end
136  end
137 
138  // set holding register
139  if (rst) hr_full <= 0;
140  else if (((&next_or_empty) && !(&drd_in)) ||
141  ((|next_or_empty) && !(|drd_in))) hr_full <= 0;
142  else if (((&drd_in) && !(&next_or_empty)) ||
143  ((|drd_in) && !(|next_or_empty))) hr_full <= 1;
144 
145  if (drd_in[1]) hr <= din[31:16];
146  else if (drd_in[0]) hr <= din[15: 0];
147 
148  if (rst || !flushing) slow_down <= 0;
149  else if (!din_avm_w) slow_down <= 1;
150 
151  if (rst || !flushing || last_dw_sent) slow_dav <= 0;
153 
154 
155  if (rst || !flushing) last_dw_sent <= 0;
156  else if (last_DW_r && dout_re) last_dw_sent <= 1;
157 
159  if (rst || !flushing) last_DW_r <= 0;
160  else if (slow_down && no_new_data_w && (&no_new_data_r)) last_DW_r <= 1;
161  else if (dout_re) last_DW_r <= 0;
162 
163  end
164 
165 endmodule
166 
13085debug_din_highwire[15:0]
13087debug_dout_highwire[15:0]
13089next_or_emptywire[1:0]
reg [31:0] 13073dout
13084debug_din_lowwire[15:0]
13086debug_dout_lowwire[15:0]