x393  1.0
FPGAcodeforElphelNC393camera
dct2d8x8_chen.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
41 module dct2d8x8_chen#(
42  parameter INPUT_WIDTH = 10,
43  parameter OUTPUT_WIDTH = 13,
44  parameter STAGE1_SAFE_BITS = 3, // leave this number of extra bits on DCT1D input to prevent output saturation
45  parameter STAGE2_SAFE_BITS = 3, // leave this number of extra bits on DCT1D input to prevent output saturation
46  parameter TRANSPOSE_WIDTH = 16, // transpose memory width
47  parameter TRIM_STAGE_1 = 1, // Trim these MSBs from the stage1 results (1 - matches old DCT)
48  parameter TRIM_STAGE_2 = 0, // Trim these MSBs from the stage2 results
49  parameter DSP_WIDTH = 24,
50 // parameter DSP_OUT_WIDTH = 24,
51  parameter DSP_B_WIDTH = 18,
52  parameter DSP_A_WIDTH = 25,
53  parameter DSP_P_WIDTH = 48
54 // parameter DSP_M_WIDTH = 43 // actual multiplier width (== (A_WIDTH +B_WIDTH)
55  ) (
56  input clk, /// system clock, posedge
57  input rst, // sync reset
58 // input en, //! if zero will reset transpose memory page njumbers
59  input start, //@ single-cycle start pulse that goes with the first pixel data. Other 63 should follow
60  input signed [INPUT_WIDTH-1:0] xin, //! [9:0] - input data
61  output reg last_in, //! output high during input of the last of 64 pixels in a 8x8 block
62  output pre_first_out, //! 1 cycle ahead of the first output in a 64 block
63  output dv, //! data output valid. WAS: Will go high on the 94-th cycle after the start
64  output signed [OUTPUT_WIDTH-1:0] d_out); //! [12:0]output data
65 
68 
73 
74 
75  reg signed [INPUT_WIDTH-1:0] xin_r;
77  reg [5:0] cntr_in = ~0;
78  reg en_in_r;
79 
80  wire signed [INPUT_WIDTH-1:0] dct1in_h;
81  wire signed [INPUT_WIDTH-1:0] dct1in_l;
82  wire dct1_start;
83  wire dct1_en;
84 
85  wire signed [DSP_WIDTH-1:0] dct1in_pad_h;
86  wire signed [DSP_WIDTH-1:0] dct1in_pad_l;
87  wire signed [TRANSPOSE_WIDTH-1:0] dct1_out;
89 // wire stage1_pre2_en_out;
90 
91  wire signed [TRANSPOSE_WIDTH-1:0] transpose_din;
92  wire signed [TRANSPOSE_WIDTH-1:0] transpose_douth;
93  wire signed [TRANSPOSE_WIDTH-1:0] transpose_doutl;
96 
97  wire signed [DSP_WIDTH-1:0] dct2in_pad_h;
98  wire signed [DSP_WIDTH-1:0] dct2in_pad_l;
99  wire signed [OUTPUT_WIDTH-1:0] dct2_out;
102 
103 // wire signed [OUTPUT_WIDTH-1:0] dct2_trimmed;
104 
107  assign transpose_din = dct1_out;
108 
109  /*
110  generate
111  if (TRIM_STAGE_1 == 0) begin
112  assign transpose_din = dct1_out[DSP_OUT_WIDTH-1 -:TRANSPOSE_WIDTH];
113  end else begin //! saturate. TODO: Maybe (and also symmetric rounding) can be done in DSP itself using masks?
114  assign transpose_din = (dct1_out[DSP_OUT_WIDTH-1 -: TRIM_STAGE_1] == {TRIM_STAGE_1{dct1_out[DSP_OUT_WIDTH-1]}})?
115  dct1_out[DSP_OUT_WIDTH-1-TRIM_STAGE_1 -: TRANSPOSE_WIDTH]:
116  {dct1_out[DSP_OUT_WIDTH-1], {TRANSPOSE_WIDTH-1{~dct1_out[DSP_OUT_WIDTH-1]}}};
117  end
118  endgenerate
119  */
120 
123 
124 // assign dct2_trimmed = dct2_out;
125  /*
126  generate
127  if (TRIM_STAGE_2 == 0) begin
128  assign dct2_trimmed = dct2_out[DSP_OUT_WIDTH-1 -: OUTPUT_WIDTH];
129  end else begin //! saturate. Maybe (and also symmetric rounding) can be done in DSP itself using masks?
130  assign dct2_trimmed = (dct2_out[DSP_OUT_WIDTH-1 -: TRIM_STAGE_2] == {TRIM_STAGE_2{dct2_out[DSP_OUT_WIDTH-1]}})?
131  dct2_out[DSP_OUT_WIDTH-1-TRIM_STAGE_2 -:OUTPUT_WIDTH]:
132  {dct2_out[DSP_OUT_WIDTH-1], {OUTPUT_WIDTH-1{~dct2_out[DSP_OUT_WIDTH-1]}}};
133  end
134  endgenerate
135  */
136 
137  always @(posedge clk) begin
138  start_in_r <= start;
139 
140  if (rst) cntr_in <= ~0;
141  else if (start) cntr_in <= 0;
142  else if (!(&cntr_in)) cntr_in <= cntr_in + 1;
143 
144  last_in <= (cntr_in == 61);
145 
146  if (rst) en_in_r <= 0;
147  else if (start) en_in_r <= 1;
148  else if (&cntr_in) en_in_r <= 0;
149 
150  if (start || en_in_r) xin_r <=xin;
151 
152  end
153 
155  .WIDTH(INPUT_WIDTH)
156  ) dct1d_chen_reorder_in_i (
157  .clk (clk), // input
158  .rst (rst), // input
159  .en (en_in_r), // input
160  .din (xin_r), // input[23:0]
161  .start (start_in_r), // input
162  .dout_10_32_76_54 ({dct1in_h,dct1in_l}), // output[47:0]
163  .start_out (dct1_start), // output reg
164  .en_out (dct1_en) // output
165  );
168  .WIDTH (DSP_WIDTH),
169  .OUT_WIDTH (TRANSPOSE_WIDTH), // DSP_OUT_WIDTH),
170  .B_WIDTH (DSP_B_WIDTH),
171  .A_WIDTH (DSP_A_WIDTH),
172  .P_WIDTH (DSP_P_WIDTH),
173  .ROUND_OUT (ROUND_STAGE1) // cut these number of LSBs on the output, round result (in addition to COSINE_SHIFT)
174  ) dct1d_chen_stage1_i (
175  .clk (clk), // input
176  .rst (rst), // input
177  .en (dct1_en), // input
178  .d10_32_76_54 ({dct1in_pad_h,dct1in_pad_l}), // input[47:0]
179  .start (dct1_start), // input
180  .dout (dct1_out), // output[23:0]
181  .pre2_start_out (stage1_pre2_start_out), // output reg
182  .en_out (dbg_stage1_pre2_en_out) // output reg
183  );
184 
186  .WIDTH(TRANSPOSE_WIDTH)
187  ) dct_chen_transpose_i (
188  .clk (clk), // input
189  .rst (rst), // input
190  .din (transpose_din), // input[23:0]
191  .pre2_start (stage1_pre2_start_out), // input
192  .dout_10_32_76_54 ({transpose_douth,transpose_doutl}), // output[47:0]
193  .start_out (transpose_start_out), // output reg
194  .en_out (transpose_en_out) // output reg
195  );
196 
198  .WIDTH (DSP_WIDTH),
199  .OUT_WIDTH (OUTPUT_WIDTH),
200  .B_WIDTH (DSP_B_WIDTH),
201  .A_WIDTH (DSP_A_WIDTH),
202  .P_WIDTH (DSP_P_WIDTH),
203  .ROUND_OUT (ROUND_STAGE2) // cut these number of LSBs on the output, round result (in addition to COSINE_SHIFT)
204  ) dct1d_chen_stage2_i (
205  .clk (clk), // input
206  .rst (rst), // input
207  .en (transpose_en_out), // input
208  .d10_32_76_54 ({dct2in_pad_h,dct2in_pad_l}), // input[47:0]
209  .start (transpose_start_out), // input
210  .dout (dct2_out), // output[23:0]
211  .pre2_start_out (stage2_pre2_start_out), // output reg
212  .en_out (stage2_pre2_en_out) // output reg
213  );
214 
216  .WIDTH (OUTPUT_WIDTH)
217  ) dct1d_chen_reorder_out_i (
218  .clk (clk), // input
219  .rst (rst), // input
220  .en (stage2_pre2_en_out), // input
221  .din (dct2_out), // input[23:0]
222  .pre2_start (stage2_pre2_start_out), // input
223  .dout (d_out), // output[23:0]
224  .start_out (pre_first_out), // output reg
225  .dv (dv), // output reg
226  .en_out () // output reg
227  );
228 
229 // Just for debugging/comparing with old 1-d DCT:
230 `ifdef SIMULATION // no sense to synthesize it
231 `ifdef DEBUG_DCT1D
232 wire [TRANSPOSE_WIDTH-1:0] dbg_d_out;
233 //wire [15:0] dbg_d_out13=dbg_d_out[7 +: 16] ;
234 wire dbg_dv;
235 wire dbg_en_out;
236 wire dbg_pre_first_out;
237 
238  dct1d_chen_reorder_out #(
239  .WIDTH (TRANSPOSE_WIDTH)
240  ) dct1d_chen_reorder_out_dbg_i (
241  .clk (clk), // input
242  .rst (rst), // input
243  .en (dbg_stage1_pre2_en_out), // input
244  .din (dct1_out), // input[23:0]
245  .pre2_start (stage1_pre2_start_out), // input
246  .dout (dbg_d_out), // output[23:0]
247  .start_out (dbg_pre_first_out), // output reg
248  .dv (dbg_dv), // output reg
249  .en_out (dbg_en_out) // output reg
250  );
251 `endif
252 `endif
253 endmodule
254 
255 
3302transpose_dinwire[TRANSPOSE_WIDTH-1:0]
Definition: dct2d8x8_chen.v:91
[2*WIDTH -1:0] 3227dout_10_32_76_54
3311stage2_pre2_en_outwire
3301stage1_pre2_start_outwire
Definition: dct2d8x8_chen.v:88
3299dct1in_pad_lwire[DSP_WIDTH-1:0]
Definition: dct2d8x8_chen.v:86
3308dct2in_pad_lwire[DSP_WIDTH-1:0]
Definition: dct2d8x8_chen.v:98
[2*WIDTH -1:0] 3318dout_10_32_76_54
[2 * WIDTH -1:0] 3138d10_32_76_54
Definition: dct1d_chen.v:62
signed [OUTPUT_WIDTH-1:0] 3283d_out
Definition: dct2d8x8_chen.v:64
3303transpose_douthwire[TRANSPOSE_WIDTH-1:0]
Definition: dct2d8x8_chen.v:92
[OUT_WIDTH -1:0] 3140dout
Definition: dct1d_chen.v:64
3304transpose_doutlwire[TRANSPOSE_WIDTH-1:0]
Definition: dct2d8x8_chen.v:93
3305transpose_start_outwire
Definition: dct2d8x8_chen.v:94
3310stage2_pre2_start_outwire
dct_chen_transpose_i dct_chen_transpose
3295dct1in_lwire[INPUT_WIDTH-1:0]
Definition: dct2d8x8_chen.v:81
3288ROUND_STAGE1DSP_WIDTH - TRANSPOSE_WIDTH - TRIM_STAGE_1
Definition: dct2d8x8_chen.v:71
3312dbg_stage1_pre2_en_outwire
signed [INPUT_WIDTH-1:0] 3279xin
Definition: dct2d8x8_chen.v:60
3306transpose_en_outwire
Definition: dct2d8x8_chen.v:95
3294dct1in_hwire[INPUT_WIDTH-1:0]
Definition: dct2d8x8_chen.v:80
dct1d_chen_stage2_i dct1d_chen
3290xin_rreg[INPUT_WIDTH-1:0]
Definition: dct2d8x8_chen.v:75
3309dct2_outwire[OUTPUT_WIDTH-1:0]
Definition: dct2d8x8_chen.v:99
3289ROUND_STAGE2DSP_WIDTH - OUTPUT_WIDTH - TRIM_STAGE_2
Definition: dct2d8x8_chen.v:72
3307dct2in_pad_hwire[DSP_WIDTH-1:0]
Definition: dct2d8x8_chen.v:97
3284REPLICATE_IN_STAGE1STAGE1_SAFE_BITS
Definition: dct2d8x8_chen.v:66
[WIDTH -1:0] 3316din
3292cntr_inreg[5:0]
Definition: dct2d8x8_chen.v:77
3285PAD_IN_STAGE1DSP_WIDTH - INPUT_WIDTH - STAGE1_SAFE_BITS
Definition: dct2d8x8_chen.v:67
dct1d_chen_reorder_out_i dct1d_chen_reorder_out
dct1d_chen_reorder_in_i dct1d_chen_reorder_in
3286REPLICATE_IN_STAGE2STAGE2_SAFE_BITS
Definition: dct2d8x8_chen.v:69
reg 3142en_out
Definition: dct1d_chen.v:67
3300dct1_outwire[TRANSPOSE_WIDTH-1:0]
Definition: dct2d8x8_chen.v:87
reg 3141pre2_start_out
Definition: dct1d_chen.v:65
3287PAD_IN_STAGE2DSP_WIDTH - TRANSPOSE_WIDTH - STAGE2_SAFE_BITS
Definition: dct2d8x8_chen.v:70
3298dct1in_pad_hwire[DSP_WIDTH-1:0]
Definition: dct2d8x8_chen.v:85