Skip to content

Commit

Permalink
support synchronous reset
Browse files Browse the repository at this point in the history
Didn't feel this was necessary at the time, but now I
found a usecase with MIPI to help keep the fifo small.
  • Loading branch information
sameer committed Mar 7, 2021
1 parent c003eba commit 33b8a60
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 31 deletions.
93 changes: 72 additions & 21 deletions src/hdmi.sv
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ module hdmi
input logic clk_pixel_x5,
input logic clk_pixel,
input logic clk_audio,
// synchronous reset back to 0,0
input logic reset,
input logic [23:0] rgb,
input logic [AUDIO_BIT_WIDTH-1:0] audio_sample_word [1:0],

Expand Down Expand Up @@ -176,14 +178,27 @@ localparam real VIDEO_RATE = (VIDEO_ID_CODE == 1 ? 25.2E6
// Wrap-around pixel position counters indicating the pixel to be generated by the user in THIS clock and sent out in the NEXT clock.
always_ff @(posedge clk_pixel)
begin
cx <= cx == frame_width-1'b1 ? BIT_WIDTH'(0) : cx + 1'b1;
cy <= cx == frame_width-1'b1 ? cy == frame_height-1'b1 ? BIT_HEIGHT'(0) : cy + 1'b1 : cy;
if (reset)
begin
cx <= BIT_WIDTH'(0);
cy <= BIT_HEIGHT'(0);
end
else
begin
cx <= cx == frame_width-1'b1 ? BIT_WIDTH'(0) : cx + 1'b1;
cy <= cx == frame_width-1'b1 ? cy == frame_height-1'b1 ? BIT_HEIGHT'(0) : cy + 1'b1 : cy;
end
end

// See Section 5.2
logic video_data_period = 0;
always_ff @(posedge clk_pixel)
video_data_period <= cx < screen_width && cy < screen_height;
begin
if (reset)
video_data_period <= 0;
else
video_data_period <= cx < screen_width && cy < screen_height;
end

logic [2:0] mode = 3'd1;
logic [23:0] video_data = 24'd0;
Expand All @@ -197,8 +212,16 @@ generate
logic video_preamble = 0;
always_ff @(posedge clk_pixel)
begin
video_guard <= cx >= frame_width - 2 && cx < frame_width && (cy == frame_height - 1 || cy < screen_height);
video_preamble <= cx >= frame_width - 10 && cx < frame_width - 2 && (cy == frame_height - 1 || cy < screen_height);
if (reset)
begin
video_guard <= 1;
video_preamble <= 0;
end
else
begin
video_guard <= cx >= frame_width - 2 && cx < frame_width && (cy == frame_height - 1 || cy < screen_height);
video_preamble <= cx >= frame_width - 10 && cx < frame_width - 2 && (cy == frame_height - 1 || cy < screen_height);
end
end

// See Section 5.2.3.1
Expand All @@ -223,9 +246,18 @@ generate
logic data_island_period = 0;
always_ff @(posedge clk_pixel)
begin
data_island_guard <= num_packets_alongside > 0 && ((cx >= screen_width + 8 && cx < screen_width + 10) || (cx >= screen_width + 10 + num_packets_alongside * 32 && cx < screen_width + 10 + num_packets_alongside * 32 + 2));
data_island_preamble <= num_packets_alongside > 0 && cx >= screen_width && cx < screen_width + 8;
data_island_period <= data_island_period_instantaneous;
if (reset)
begin
data_island_guard <= 0;
data_island_preamble <= 0;
data_island_period <= 0;
end
else
begin
data_island_guard <= num_packets_alongside > 0 && ((cx >= screen_width + 8 && cx < screen_width + 10) || (cx >= screen_width + 10 + num_packets_alongside * 32 && cx < screen_width + 10 + num_packets_alongside * 32 + 2));
data_island_preamble <= num_packets_alongside > 0 && cx >= screen_width && cx < screen_width + 8;
data_island_period <= data_island_period_instantaneous;
end
end

// See Section 5.2.3.4
Expand All @@ -242,29 +274,48 @@ generate
.VENDOR_NAME(VENDOR_NAME),
.PRODUCT_DESCRIPTION(PRODUCT_DESCRIPTION),
.SOURCE_DEVICE_INFORMATION(SOURCE_DEVICE_INFORMATION)
) packet_picker (.clk_pixel(clk_pixel), .clk_audio(clk_audio), .video_field_end(video_field_end), .packet_enable(packet_enable), .packet_pixel_counter(packet_pixel_counter), .audio_sample_word(audio_sample_word), .header(header), .sub(sub));
) packet_picker (.clk_pixel(clk_pixel), .clk_audio(clk_audio), .reset(reset), .video_field_end(video_field_end), .packet_enable(packet_enable), .packet_pixel_counter(packet_pixel_counter), .audio_sample_word(audio_sample_word), .header(header), .sub(sub));
logic [8:0] packet_data;
packet_assembler packet_assembler (.clk_pixel(clk_pixel), .data_island_period(data_island_period), .header(header), .sub(sub), .packet_data(packet_data), .counter(packet_pixel_counter));
packet_assembler packet_assembler (.clk_pixel(clk_pixel), .reset(reset), .data_island_period(data_island_period), .header(header), .sub(sub), .packet_data(packet_data), .counter(packet_pixel_counter));


always_ff @(posedge clk_pixel)
begin
mode <= data_island_guard ? 3'd4 : data_island_period ? 3'd3 : video_guard ? 3'd2 : video_data_period ? 3'd1 : 3'd0;
video_data <= rgb;
control_data <= {{1'b0, data_island_preamble}, {1'b0, video_preamble || data_island_preamble}, {vsync, hsync}}; // ctrl3, ctrl2, ctrl1, ctrl0, vsync, hsync
data_island_data[11:4] <= packet_data[8:1];
data_island_data[3] <= cx != 0;
data_island_data[2] <= packet_data[0];
data_island_data[1:0] <= {vsync, hsync};
if (reset)
begin
mode <= 3'd2;
video_data <= 24'd0;
control_data = 6'd0;
data_island_data <= 12'd0;
end
else
begin
mode <= data_island_guard ? 3'd4 : data_island_period ? 3'd3 : video_guard ? 3'd2 : video_data_period ? 3'd1 : 3'd0;
video_data <= rgb;
control_data <= {{1'b0, data_island_preamble}, {1'b0, video_preamble || data_island_preamble}, {vsync, hsync}}; // ctrl3, ctrl2, ctrl1, ctrl0, vsync, hsync
data_island_data[11:4] <= packet_data[8:1];
data_island_data[3] <= cx != 0;
data_island_data[2] <= packet_data[0];
data_island_data[1:0] <= {vsync, hsync};
end
end
end
else // DVI_OUTPUT = 1
begin
always_ff @(posedge clk_pixel)
begin
mode <= video_data_period;
video_data <= rgb;
control_data <= {4'b0000, {vsync, hsync}}; // ctrl3, ctrl2, ctrl1, ctrl0, vsync, hsync
if (reset)
begin
mode <= 3'd0;
video_data <= 24'd0;
control_data <= 6'd0;
end
else
begin
mode <= video_data_period ? 3'd1 : 3'd0;
video_data <= rgb;
control_data <= {4'b0000, {vsync, hsync}}; // ctrl3, ctrl2, ctrl1, ctrl0, vsync, hsync
end
end
end
endgenerate
Expand All @@ -280,6 +331,6 @@ generate
end
endgenerate

serializer #(.NUM_CHANNELS(NUM_CHANNELS), .VIDEO_RATE(VIDEO_RATE)) serializer(.clk_pixel(clk_pixel), .clk_pixel_x5(clk_pixel_x5), .tmds_internal(tmds_internal), .tmds(tmds), .tmds_clock(tmds_clock));
serializer #(.NUM_CHANNELS(NUM_CHANNELS), .VIDEO_RATE(VIDEO_RATE)) serializer(.clk_pixel(clk_pixel), .clk_pixel_x5(clk_pixel_x5), .reset(reset), .tmds_internal(tmds_internal), .tmds(tmds), .tmds_clock(tmds_clock));

endmodule
12 changes: 9 additions & 3 deletions src/packet_assembler.sv
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

module packet_assembler (
input logic clk_pixel,
input logic reset,
input logic data_island_period,
input logic [23:0] header, // See Table 5-8 Packet Types
input logic [55:0] sub [3:0],
Expand All @@ -12,9 +13,12 @@ module packet_assembler (

// 32 pixel wrap-around counter. See Section 5.2.3.4 for further information.
always_ff @(posedge clk_pixel)
if (data_island_period)
begin
if (reset)
counter <= 5'd0;
else if (data_island_period)
counter <= counter + 5'd1;

end
// BCH packets 0 to 3 are transferred two bits at a time, see Section 5.2.3.4 for further information.
wire [5:0] counter_t2 = {counter, 1'b0};
wire [5:0] counter_t2_p1 = {counter, 1'b1};
Expand Down Expand Up @@ -62,7 +66,9 @@ endgenerate

always_ff @(posedge clk_pixel)
begin
if (data_island_period)
if (reset)
parity <= '{8'd0, 8'd0, 8'd0, 8'd0, 8'd0};
else if (data_island_period)
begin
if (counter < 5'd28) // Compute ECC only on subpacket data, not on itself
begin
Expand Down
9 changes: 7 additions & 2 deletions src/packet_picker.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module packet_picker
(
input logic clk_pixel,
input logic clk_audio,
input logic reset,
input logic video_field_end,
input logic packet_enable,
input logic [4:0] packet_pixel_counter,
Expand Down Expand Up @@ -115,7 +116,11 @@ logic [7:0] frame_counter = 8'd0;
int k;
always_ff @(posedge clk_pixel)
begin
if (packet_pixel_counter == 5'd31 && packet_type == 8'h02) // Keep track of current IEC 60958 frame
if (reset)
begin
frame_counter <= 8'd0;
end
else if (packet_pixel_counter == 5'd31 && packet_type == 8'h02) // Keep track of current IEC 60958 frame
begin
frame_counter = frame_counter + 8'd4;
if (frame_counter >= 8'd192)
Expand Down Expand Up @@ -144,7 +149,7 @@ begin
if (sample_buffer_used)
sample_buffer_used <= 1'b0;

if (video_field_end)
if (reset || video_field_end)
begin
audio_info_frame_sent <= 1'b0;
auxiliary_video_information_info_frame_sent <= 1'b0;
Expand Down
12 changes: 7 additions & 5 deletions src/serializer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module serializer
(
input logic clk_pixel,
input logic clk_pixel_x5,
input logic reset,
input logic [9:0] tmds_internal [NUM_CHANNELS-1:0],
output logic [2:0] tmds,
output logic tmds_clock
Expand All @@ -21,10 +22,11 @@ module serializer
assign tmds_internal_plus_clock = '{10'b0000011111, tmds_internal[2], tmds_internal[1], tmds_internal[0]};
logic [1:0] cascade [NUM_CHANNELS:0];

logic reset = 1'b1;
// this is requried for OSERDESE2 to work
logic internal_reset = 1'b1;
always @(posedge clk_pixel)
begin
reset <= 1'b0;
internal_reset <= 1'b0;
end
genvar i;
generate
Expand Down Expand Up @@ -59,7 +61,7 @@ module serializer
.TCE(1'b0),
.OCE(1'b1),
.TBYTEIN(1'b0),
.RST(reset),
.RST(reset || internal_reset),
.SHIFTIN1(cascade[i][0]),
.SHIFTIN2(cascade[i][1]),
.T1(1'b0),
Expand Down Expand Up @@ -96,7 +98,7 @@ module serializer
.TCE(1'b0),
.OCE(1'b1),
.TBYTEIN(1'b0),
.RST(reset),
.RST(reset || internal_reset),
.SHIFTIN1(1'b0),
.SHIFTIN2(1'b0),
.T1(1'b0),
Expand Down Expand Up @@ -142,7 +144,7 @@ module serializer
.pll_areset (1'b0),
.sync_inclock (1'b0),
.tx_coreclock (),
.tx_data_reset (1'b0),
.tx_data_reset (reset),
.tx_enable (1'b1),
.tx_locked (),
.tx_pll_enable (1'b1),
Expand Down
2 changes: 2 additions & 0 deletions top/top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ logic tmds_clock;
logic clk_pixel;
logic clk_pixel_x5;
logic clk_audio;
logic reset;

pll pll(.c0(clk_pixel_x5), .c1(clk_pixel), .c2(clk_audio));

Expand All @@ -23,6 +24,7 @@ hdmi #(.VIDEO_ID_CODE(1), .VIDEO_REFRESH_RATE(59.94), .AUDIO_RATE(48000), .AUDIO
.clk_pixel_x5(clk_pixel_x5),
.clk_pixel(clk_pixel),
.clk_audio(clk_audio),
.reset(reset),
.rgb(rgb),
.audio_sample_word(audio_sample_word),
.tmds(tmds),
Expand Down

0 comments on commit 33b8a60

Please sign in to comment.