2023-05-30 11:33:08 +00:00
|
|
|
module lvds_tx (
|
2024-03-16 10:14:41 +00:00
|
|
|
input i_rst_b,
|
|
|
|
input i_ddr_clk,
|
2023-07-03 11:40:33 +00:00
|
|
|
output reg[1:0] o_ddr_data,
|
2023-05-30 11:33:08 +00:00
|
|
|
|
2024-03-16 10:14:41 +00:00
|
|
|
input i_fifo_empty,
|
|
|
|
output o_fifo_read_clk,
|
2023-07-03 11:40:33 +00:00
|
|
|
output o_fifo_pull,
|
2024-03-16 10:14:41 +00:00
|
|
|
input [31:0] i_fifo_data,
|
2023-07-03 11:40:33 +00:00
|
|
|
input [3:0] i_sample_gap,
|
2024-03-16 10:14:41 +00:00
|
|
|
input i_tx_state,
|
|
|
|
input i_sync_input,
|
2023-07-03 11:40:33 +00:00
|
|
|
input i_debug_lb,
|
|
|
|
output o_tx_state_bit,
|
|
|
|
output o_sync_state_bit,
|
2023-05-30 11:33:08 +00:00
|
|
|
);
|
|
|
|
|
2023-07-03 11:40:33 +00:00
|
|
|
// STATES and PARAMS
|
|
|
|
localparam
|
2024-03-16 10:14:41 +00:00
|
|
|
tx_state_sync = 1'b0,
|
|
|
|
tx_state_tx = 1'b1;
|
2023-07-03 11:40:33 +00:00
|
|
|
localparam sync_duration_frames = 4'd10; // at least 2.5usec
|
|
|
|
localparam zero_frame = 32'b00000000_00000000_00000000_00000000;
|
|
|
|
localparam lb_frame = 32'b10000100_00000011_01110000_01001000;
|
2024-03-16 10:14:41 +00:00
|
|
|
|
|
|
|
// Internal Registers
|
2023-07-03 11:40:33 +00:00
|
|
|
reg [3:0] r_sync_count;
|
|
|
|
wire frame_pull_clock;
|
|
|
|
wire frame_assign_clock;
|
|
|
|
reg r_state;
|
|
|
|
reg [3:0] r_phase_count;
|
2024-03-16 10:14:41 +00:00
|
|
|
reg [31:0] r_fifo_data;
|
2023-07-03 11:40:33 +00:00
|
|
|
reg r_pulled;
|
|
|
|
reg r_schedule_zero_frame;
|
2023-05-16 13:28:08 +00:00
|
|
|
|
2024-03-16 10:14:41 +00:00
|
|
|
// Initial conditions
|
|
|
|
initial begin
|
2023-07-03 11:40:33 +00:00
|
|
|
r_phase_count = 4'd15;
|
|
|
|
r_fifo_data <= zero_frame;
|
2024-03-16 10:14:41 +00:00
|
|
|
end
|
2023-05-16 13:28:08 +00:00
|
|
|
|
2024-03-16 10:14:41 +00:00
|
|
|
assign o_fifo_read_clk = i_ddr_clk;
|
2023-07-03 11:40:33 +00:00
|
|
|
assign o_tx_state_bit = r_state;
|
|
|
|
assign o_sync_state_bit = 1'b0;
|
|
|
|
assign o_fifo_pull = r_pulled;
|
2023-05-30 11:33:08 +00:00
|
|
|
|
2023-07-03 11:40:33 +00:00
|
|
|
// SHIFT REGISTER
|
|
|
|
always @(posedge i_ddr_clk) begin
|
|
|
|
if (i_rst_b == 1'b0) begin
|
|
|
|
r_phase_count <= 4'd15;
|
|
|
|
end else begin
|
|
|
|
o_ddr_data[1:0] <= r_fifo_data[2*r_phase_count+1 : 2*r_phase_count];
|
|
|
|
r_phase_count <= r_phase_count - 1;
|
|
|
|
end
|
|
|
|
end
|
2024-03-16 10:14:41 +00:00
|
|
|
|
2023-07-03 11:40:33 +00:00
|
|
|
// SYNC AND MANAGEMENT
|
2024-03-16 10:14:41 +00:00
|
|
|
always @(posedge i_ddr_clk)
|
|
|
|
begin
|
|
|
|
if (i_rst_b == 1'b0) begin
|
2023-07-03 11:40:33 +00:00
|
|
|
r_state <= tx_state_sync;
|
|
|
|
r_pulled <= 1'b0;
|
|
|
|
r_fifo_data <= zero_frame;
|
|
|
|
r_sync_count <= sync_duration_frames;
|
|
|
|
r_schedule_zero_frame <= 1'b0;
|
2024-03-16 10:14:41 +00:00
|
|
|
end else begin
|
2023-07-03 11:40:33 +00:00
|
|
|
case (r_state)
|
|
|
|
//----------------------------------------------
|
|
|
|
tx_state_sync:
|
|
|
|
begin
|
|
|
|
if (r_phase_count == 4'd0) begin
|
|
|
|
if (r_schedule_zero_frame) begin
|
|
|
|
r_fifo_data <= zero_frame;
|
|
|
|
r_schedule_zero_frame <= 1'b0;
|
|
|
|
end
|
|
|
|
end else if (r_phase_count == 4'd1) begin
|
|
|
|
if (r_sync_count == 4'd0) begin
|
|
|
|
if (i_debug_lb && !i_tx_state) begin
|
|
|
|
r_fifo_data <= lb_frame;
|
|
|
|
r_state <= tx_state_sync;
|
|
|
|
end else if (!i_debug_lb && i_tx_state) begin
|
|
|
|
r_pulled <= !i_fifo_empty;
|
|
|
|
r_state <= tx_state_tx;
|
|
|
|
end else begin
|
|
|
|
r_sync_count <= sync_duration_frames;
|
|
|
|
r_state <= tx_state_sync;
|
|
|
|
r_fifo_data <= zero_frame;
|
|
|
|
end
|
2024-03-16 10:14:41 +00:00
|
|
|
end else begin
|
2023-07-03 11:40:33 +00:00
|
|
|
r_sync_count <= r_sync_count - 1;
|
|
|
|
r_schedule_zero_frame <= 1'b1;
|
|
|
|
//r_fifo_data <= zero_frame;
|
|
|
|
r_state <= tx_state_sync;
|
2024-03-16 10:14:41 +00:00
|
|
|
end
|
2023-07-03 11:40:33 +00:00
|
|
|
end
|
|
|
|
end
|
2024-03-16 10:14:41 +00:00
|
|
|
|
2023-07-03 11:40:33 +00:00
|
|
|
//----------------------------------------------
|
|
|
|
tx_state_tx:
|
|
|
|
begin
|
|
|
|
if (i_debug_lb || !i_tx_state) begin
|
|
|
|
r_state <= tx_state_sync;
|
|
|
|
r_sync_count <= sync_duration_frames;
|
|
|
|
r_pulled <= 1'b0;
|
|
|
|
end else if (r_phase_count == 4'd1) begin
|
|
|
|
r_pulled <= !i_fifo_empty;
|
|
|
|
r_state <= tx_state_tx;
|
|
|
|
end else if (r_phase_count == 4'd0) begin
|
|
|
|
if (r_pulled == 1'b0) begin
|
|
|
|
r_sync_count <= sync_duration_frames;
|
|
|
|
r_fifo_data <= zero_frame;
|
|
|
|
r_state <= tx_state_sync;
|
2024-03-16 10:14:41 +00:00
|
|
|
end else begin
|
2023-07-03 11:40:33 +00:00
|
|
|
r_fifo_data <= i_fifo_data;
|
|
|
|
if (i_sample_gap > 0) begin
|
|
|
|
r_sync_count <= i_sample_gap;
|
|
|
|
r_state <= tx_state_sync;
|
|
|
|
end else begin
|
|
|
|
r_state <= tx_state_tx;
|
|
|
|
end
|
|
|
|
end
|
2024-03-16 10:14:41 +00:00
|
|
|
|
2023-07-03 11:40:33 +00:00
|
|
|
r_pulled <= 1'b0;
|
2024-03-16 10:14:41 +00:00
|
|
|
end
|
2023-07-03 11:40:33 +00:00
|
|
|
end
|
|
|
|
endcase
|
2024-03-16 10:14:41 +00:00
|
|
|
end
|
2023-05-16 13:28:08 +00:00
|
|
|
end
|
2023-05-30 11:33:08 +00:00
|
|
|
endmodule
|