Optimization, better modulo-10 divider.

This commit is contained in:
Bruno Levy
2021-01-01 16:28:56 +01:00
parent a471aa9dad
commit 13552446e0

View File

@@ -47,9 +47,12 @@ always @(posedge pixclk) vSync <= (CounterY>=490) && (CounterY<492);
wire [7:0] W = {8{CounterX[7:0]==CounterY[7:0]}};
wire [7:0] A = {8{CounterX[7:5]==3'h2 && CounterY[7:5]==3'h2}};
reg [7:0] red, green, blue;
always @(posedge pixclk) red <= ({CounterX[5:0] & {6{CounterY[4:3]==~CounterX[4:3]}}, 2'b00} | W) & ~A;
always @(posedge pixclk) green <= (CounterX[7:0] & {8{CounterY[6]}} | W) & ~A;
always @(posedge pixclk) blue <= CounterY[7:0] | W | A;
always @(posedge pixclk) begin
red <= ({CounterX[5:0] & {6{CounterY[4:3]==~CounterX[4:3]}}, 2'b00} | W) & ~A;
green <= (CounterX[7:0] & {8{CounterY[6]}} | W) & ~A;
blue <= CounterY[7:0] | W | A;
end
/******** RGB TMDS encoding ***************************************************/
wire [9:0] TMDS_red, TMDS_green, TMDS_blue;
@@ -60,21 +63,27 @@ TMDS_encoder encode_B(.clk(pixclk), .VD(blue ), .CD({vSync,hSync}), .VDE(DrawAre
/******** 250 MHz clock *******************************************************/
// This one needs some FPGA-specific specialized blocks
wire clk_TMDS;
HDMI_clock hdmi_clock(.clk(pixclk), .hdmi_clk(clk_TMDS));
wire clk_pix2;
HDMI_clock hdmi_clock(.clk(pixclk), .hdmi_clk(clk_TMDS), .out_clk(clk_pix2));
/******** Shifter *************************************************************/
// Q: can we use the 25 MHz output clock of HDMI_clock instead of recomputing mod10 ?
// Q: can we use Olof's trick (decrement, test sign bit) ?
reg [3:0] TMDS_mod10=0; // modulus 10 counter
// Modulo-10 counter (note: most code I found uses a counter reset to 0 when
// it reaches 9. For a small modulo, I prefer to have a circular shift-buffer
// with a single 1 that triggers the signal. I think it is more elegant, and
// more importantly, it works for a higher fmax (450 MHz here).
reg [9:0] TMDS_mod10=1;
wire TMDS_shift_load = TMDS_mod10[9];
always @(posedge clk_TMDS) begin
TMDS_mod10 <= {TMDS_mod10[8:0],TMDS_mod10[9]};
end
reg [9:0] TMDS_shift_red=0, TMDS_shift_green=0, TMDS_shift_blue=0;
reg TMDS_shift_load=0;
always @(posedge clk_TMDS) TMDS_shift_load <= (TMDS_mod10==4'd9);
always @(posedge clk_TMDS) begin
TMDS_shift_red <= TMDS_shift_load ? TMDS_red : TMDS_shift_red [9:1];
TMDS_shift_green <= TMDS_shift_load ? TMDS_green : TMDS_shift_green[9:1];
TMDS_shift_blue <= TMDS_shift_load ? TMDS_blue : TMDS_shift_blue [9:1];
TMDS_mod10 <= (TMDS_mod10==4'd9) ? 4'd0 : TMDS_mod10+4'd1;
end
/******** Output to HDMI *****************************************************/