11//
2- // Copyright (C) 2019-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
2+ // Copyright (C) 2019-2025 Markus Hiienkari <mhiienka@niksula.hut.fi>
33//
44// This file is part of Open Source Scan Converter project.
55//
@@ -103,8 +103,8 @@ localparam PP_SHMASK_END = PP_SHMASK_START + PP_SHMASK_LENGTH;
103103localparam PP_Y_CALC_START = PP_SRCSEL_END;
104104localparam PP_Y_CALC_LENGTH = 2 ;
105105localparam PP_Y_CALC_END = PP_Y_CALC_START + PP_Y_CALC_LENGTH;
106- localparam PP_SLGEN_START = PP_Y_CALC_END;
107- localparam PP_SLGEN_LENGTH = 5 ;
106+ localparam PP_SLGEN_START = PP_Y_CALC_END- 1 ;
107+ localparam PP_SLGEN_LENGTH = 6 ;
108108localparam PP_SLGEN_END = PP_SLGEN_START + PP_SLGEN_LENGTH;
109109localparam PP_TP_START = PP_SLGEN_END;
110110localparam PP_TP_LENGTH = 1 ;
@@ -182,7 +182,7 @@ reg line_id;
182182reg ypos_pp_init, ypos_lb_repeatfirst;
183183
184184reg sl_method;
185- reg [3 :0 ] sl_str;
185+ reg [3 :0 ] sl_str, sl_str_q ;
186186reg [7 :0 ] sl_str_thold, Y_sl_str, R_sl_str, G_sl_str, B_sl_str;
187187wire [7 :0 ] R_sl_mult, G_sl_mult, B_sl_mult;
188188reg [3 :0 ] bfi_frame_ctr;
@@ -214,6 +214,7 @@ reg [3:0] y_ctr_sl_pp[PP_PL_START:PP_SLGEN_START] /* synthesis ramstyle = "logic
214214assign PCLK_o = PCLK_OUT_i;
215215
216216
217+ // SLGEN cycle 2
217218lpm_mult_8x5_9 Y_sl_hybr_ref_pre_u
218219(
219220 .clock(PCLK_OUT_i),
@@ -224,76 +225,79 @@ lpm_mult_8x5_9 Y_sl_hybr_ref_pre_u
224225lpm_mult_8x5_9 R_sl_hybr_ref_pre_u
225226(
226227 .clock(PCLK_OUT_i),
227- .dataa(R_pp[PP_SLGEN_START]),
228+ .dataa(R_pp[PP_SLGEN_START+ 1 ]),
228229 .datab(SL_HYBRSTR),
229230 .result(R_sl_hybr_ref_pre)
230231);
231232lpm_mult_8x5_9 G_sl_hybr_ref_pre_u
232233(
233234 .clock(PCLK_OUT_i),
234- .dataa(G_pp[PP_SLGEN_START]),
235+ .dataa(G_pp[PP_SLGEN_START+ 1 ]),
235236 .datab(SL_HYBRSTR),
236237 .result(G_sl_hybr_ref_pre)
237238);
238239lpm_mult_8x5_9 B_sl_hybr_ref_pre_u
239240(
240241 .clock(PCLK_OUT_i),
241- .dataa(B_pp[PP_SLGEN_START]),
242+ .dataa(B_pp[PP_SLGEN_START+ 1 ]),
242243 .datab(SL_HYBRSTR),
243244 .result(B_sl_hybr_ref_pre)
244245);
245246
247+ // SLGEN cycle 3
246248lpm_mult_8x5_9 Y_sl_hybr_ref_u
247249(
248250 .clock(PCLK_OUT_i),
249251 .dataa(Y_sl_hybr_ref_pre[8 :1 ]),
250- .datab({sl_str , 1'b0 }),
252+ .datab({sl_str_q , 1'b0 }),
251253 .result(Y_sl_hybr_ref)
252254);
253255lpm_mult_8x5_9 R_sl_hybr_ref_u
254256(
255257 .clock(PCLK_OUT_i),
256258 .dataa(R_sl_hybr_ref_pre[8 :1 ]),
257- .datab({sl_str , 1'b0 }),
259+ .datab({sl_str_q , 1'b0 }),
258260 .result(R_sl_hybr_ref)
259261);
260262lpm_mult_8x5_9 G_sl_hybr_ref_u
261263(
262264 .clock(PCLK_OUT_i),
263265 .dataa(G_sl_hybr_ref_pre[8 :1 ]),
264- .datab({sl_str , 1'b0 }),
266+ .datab({sl_str_q , 1'b0 }),
265267 .result(G_sl_hybr_ref)
266268);
267269lpm_mult_8x5_9 B_sl_hybr_ref_u
268270(
269271 .clock(PCLK_OUT_i),
270272 .dataa(B_sl_hybr_ref_pre[8 :1 ]),
271- .datab({sl_str , 1'b0 }),
273+ .datab({sl_str_q , 1'b0 }),
272274 .result(B_sl_hybr_ref)
273275);
274276
277+ // SLGEN cycle 5
275278lpm_mult_sl R_sl_mult_u
276279(
277280 .clock(PCLK_OUT_i),
278- .dataa(R_pp[PP_SLGEN_START+3 ]),
281+ .dataa(R_pp[PP_SLGEN_START+4 ]),
279282 .datab(~Y_sl_str),
280283 .result(R_sl_mult)
281284);
282285lpm_mult_sl G_sl_mult_u
283286(
284287 .clock(PCLK_OUT_i),
285- .dataa(G_pp[PP_SLGEN_START+3 ]),
288+ .dataa(G_pp[PP_SLGEN_START+4 ]),
286289 .datab(~Y_sl_str),
287290 .result(G_sl_mult)
288291);
289292lpm_mult_sl B_sl_mult_u
290293(
291294 .clock(PCLK_OUT_i),
292- .dataa(B_pp[PP_SLGEN_START+3 ]),
295+ .dataa(B_pp[PP_SLGEN_START+4 ]),
293296 .datab(~Y_sl_str),
294297 .result(B_sl_mult)
295298);
296299
300+ // SHMASK cycle 2
297301lpm_mult_8x5_9 R_shmask_mult_u
298302(
299303 .clock(PCLK_OUT_i),
416420// | | | | SRCSEL | | | | | | | | |
417421// | | SHM_BUF | SHM_BUF | SHMASK | SHMASK | SHMASK | | | | | | |
418422// | | | | | Y | Y | | | | | | |
419- // | | | | | | | SLGEN | SLGEN | SLGEN | SLGEN | SLGEN | |
423+ // | | | | | | SLGEN | SLGEN | SLGEN | SLGEN | SLGEN | SLGEN | |
420424// | | | | | | | | | | | | TP |
421425
422426
@@ -570,7 +574,7 @@ always @(posedge PCLK_OUT_i) begin
570574 G_pp[PP_SHMASK_END] <= MISC_SHMASK_ENABLE ? (G_shmask_mult[8 ] ? 8'hff : G_shmask_mult[7 :0 ]) : G_pp[PP_SHMASK_START+ 2 ];
571575 B_pp[PP_SHMASK_END] <= MISC_SHMASK_ENABLE ? (B_shmask_mult[8 ] ? 8'hff : B_shmask_mult[7 :0 ]) : B_pp[PP_SHMASK_START+ 2 ];
572576
573- /* ---------- Scanline generation (5 cycles) ---------- */
577+ /* ---------- Scanline generation (6 cycles) ---------- */
574578 if (bfi_frame_ctr > MISC_BFI_THOLD) begin
575579 sl_str <= MISC_BFI_STR;
576580 sl_method <= 1'b1 ;
@@ -591,24 +595,28 @@ always @(posedge PCLK_OUT_i) begin
591595 end
592596
593597 // Cycle 2
594- sl_str_thold <= ((sl_str+ 8'h01 )<< 4 )- 1'b1 ;
598+ // register inferred in DSP block (sl_hybr_ref), avoid critical timing path due to routing delays
599+ sl_str_q <= sl_str;
595600
596601 // Cycle 3
602+ sl_str_thold <= ((sl_str_q+ 8'h01 )<< 4 )- 1'b1 ;
603+
604+ // Cycle 4
597605 Y_sl_str <= ({1'b0 , sl_str_thold} < Y_sl_hybr_ref) ? 8'h0 : sl_str_thold - Y_sl_hybr_ref[7 :0 ];
598606 R_sl_str <= ({1'b0 , sl_str_thold} < R_sl_hybr_ref) ? 8'h0 : sl_str_thold - R_sl_hybr_ref[7 :0 ];
599607 G_sl_str <= ({1'b0 , sl_str_thold} < G_sl_hybr_ref) ? 8'h0 : sl_str_thold - G_sl_hybr_ref[7 :0 ];
600608 B_sl_str <= ({1'b0 , sl_str_thold} < B_sl_hybr_ref) ? 8'h0 : sl_str_thold - B_sl_hybr_ref[7 :0 ];
601609
602- // Cycle 4
603- // store subtraction based scanlined RGB into pipeline registers
604- R_pp[PP_SLGEN_START+ 4 ] <= draw_sl_pp[PP_SLGEN_START+ 3 ] ? ((R_pp[PP_SLGEN_START+ 3 ] > R_sl_str) ? (R_pp[PP_SLGEN_START+ 3 ] - R_sl_str) : 8'h00 ) : R_pp[PP_SLGEN_START+ 3 ];
605- G_pp[PP_SLGEN_START+ 4 ] <= draw_sl_pp[PP_SLGEN_START+ 3 ] ? ((G_pp[PP_SLGEN_START+ 3 ] > G_sl_str) ? (G_pp[PP_SLGEN_START+ 3 ] - G_sl_str) : 8'h00 ) : G_pp[PP_SLGEN_START+ 3 ];
606- B_pp[PP_SLGEN_START+ 4 ] <= draw_sl_pp[PP_SLGEN_START+ 3 ] ? ((B_pp[PP_SLGEN_START+ 3 ] > B_sl_str) ? (B_pp[PP_SLGEN_START+ 3 ] - B_sl_str) : 8'h00 ) : B_pp[PP_SLGEN_START+ 3 ];
607-
608610 // Cycle 5
609- R_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+ 4 ] & sl_method) ? R_sl_mult : R_pp[PP_SLGEN_START+ 4 ];
610- G_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+ 4 ] & sl_method) ? G_sl_mult : G_pp[PP_SLGEN_START+ 4 ];
611- B_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+ 4 ] & sl_method) ? B_sl_mult : B_pp[PP_SLGEN_START+ 4 ];
611+ // store subtraction based scanlined RGB into pipeline registers
612+ R_pp[PP_SLGEN_START+ 5 ] <= draw_sl_pp[PP_SLGEN_START+ 4 ] ? ((R_pp[PP_SLGEN_START+ 4 ] > R_sl_str) ? (R_pp[PP_SLGEN_START+ 4 ] - R_sl_str) : 8'h00 ) : R_pp[PP_SLGEN_START+ 4 ];
613+ G_pp[PP_SLGEN_START+ 5 ] <= draw_sl_pp[PP_SLGEN_START+ 4 ] ? ((G_pp[PP_SLGEN_START+ 4 ] > G_sl_str) ? (G_pp[PP_SLGEN_START+ 4 ] - G_sl_str) : 8'h00 ) : G_pp[PP_SLGEN_START+ 4 ];
614+ B_pp[PP_SLGEN_START+ 5 ] <= draw_sl_pp[PP_SLGEN_START+ 4 ] ? ((B_pp[PP_SLGEN_START+ 4 ] > B_sl_str) ? (B_pp[PP_SLGEN_START+ 4 ] - B_sl_str) : 8'h00 ) : B_pp[PP_SLGEN_START+ 4 ];
615+
616+ // Cycle 6
617+ R_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+ 5 ] & sl_method) ? R_sl_mult : R_pp[PP_SLGEN_START+ 5 ];
618+ G_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+ 5 ] & sl_method) ? G_sl_mult : G_pp[PP_SLGEN_START+ 5 ];
619+ B_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+ 5 ] & sl_method) ? B_sl_mult : B_pp[PP_SLGEN_START+ 5 ];
612620
613621 /* ---------- Testpattern / mask generation ---------- */
614622 R_pp[PP_TP_END] <= testpattern_enable ? (xpos_pp[PP_TP_START] ^ ypos_pp[PP_TP_START]) : (mask_enable_pp[PP_TP_START] ? MASK_R : R_pp[PP_TP_START]);
0 commit comments