Revision 951
Added by markw about 6 years ago
| eclaireXL_ITX/hdmi/hdmi.vhd | ||
|---|---|---|
|
port (
|
||
|
-- clocks
|
||
|
I_CLK_PIXEL : in std_logic;
|
||
|
I_RESET : in std_logic;
|
||
|
|
||
|
-- components
|
||
|
I_R : in std_logic_vector(7 downto 0);
|
||
| ... | ... | |
|
);
|
||
|
port (
|
||
|
i_pixclk : in std_logic;
|
||
|
i_reset : in std_logic;
|
||
|
i_hSync : in std_logic;
|
||
|
i_vSync : in std_logic;
|
||
|
i_blank : in std_logic;
|
||
| ... | ... | |
|
)
|
||
|
port map(
|
||
|
i_pixclk => I_CLK_PIXEL,
|
||
|
i_reset => I_RESET,
|
||
|
i_blank => I_BLANK,
|
||
|
i_hSync => I_HSYNC,
|
||
|
i_vSync => I_VSYNC,
|
||
| eclaireXL_ITX/hdmi/hdmidataencoder.v | ||
|---|---|---|
|
//---------------------------------------------------------------------------
|
||
|
//-- (c) 2016 Alexey Spirkov
|
||
|
//-- I am happy for anyone to use this for non-commercial use.
|
||
|
//-- If my verilog/vhdl/c files are used commercially or otherwise sold,
|
||
| ... | ... | |
|
#(parameter FREQ=27000000, FS=48000, CTS=27000, N=6144)
|
||
|
(
|
||
|
input i_pixclk,
|
||
|
input i_reset,
|
||
|
input i_hSync,
|
||
|
input i_vSync,
|
||
|
input i_blank,
|
||
| ... | ... | |
|
reg [10:0] audioAvgCnt;
|
||
|
reg [15:0] counterX;
|
||
|
reg firstHSyncChange;
|
||
|
reg firstVSyncChange;
|
||
|
reg oddLine;
|
||
|
reg prevHSync;
|
||
|
reg prevVSync;
|
||
|
reg prevBlank;
|
||
|
reg allowGeneration;
|
||
|
|
||
|
reg packet_sent;
|
||
|
wire packet_needed;
|
||
|
reg start_of_frame;
|
||
|
reg audio_regen_needed;
|
||
|
reg packet_ready;
|
||
|
wire audio_regen;
|
||
|
wire audio_info;
|
||
|
wire video_info;
|
||
|
|
||
|
initial
|
||
|
begin
|
||
|
audioPacketHeader=0;
|
||
| ... | ... | |
|
oddLine=0;
|
||
|
counterX=0;
|
||
|
prevHSync = 0;
|
||
|
prevVSync = 0;
|
||
|
prevBlank = 0;
|
||
|
firstHSyncChange = 0;
|
||
|
firstVSyncChange = 0;
|
||
|
allowGeneration = 0;
|
||
|
audioRAvg = 0;
|
||
|
audioLAvg = 0;
|
||
|
audioRAvgSum = 0;
|
||
|
audioLAvgSum = 0;
|
||
|
audioAvgCnt = 1;
|
||
|
packet_ready = 0;
|
||
|
end
|
||
|
|
||
|
function [7:0] ECCcode; // Cycles the error code generator
|
||
| ... | ... | |
|
end
|
||
|
endtask
|
||
|
|
||
|
infopacketstate infopacketstate1 (
|
||
|
i_pixclk, i_reset, start_of_frame, audio_regen_needed, packet_sent, audio_regen, audio_info, video_info, packet_needed);
|
||
|
|
||
|
task InfoGen;
|
||
|
inout [16:0] _timer;
|
||
|
inout _audio_regen_needed;
|
||
|
inout _packet_ready;
|
||
|
begin
|
||
|
if (_timer >= CTS) begin
|
||
|
_audio_regen_needed <= 1'b1;
|
||
|
_timer <= _timer - CTS + 1;
|
||
|
end
|
||
|
|
||
|
_packet_ready <= 0;
|
||
|
|
||
|
if (audio_regen) begin
|
||
|
packetHeader<=24'h000001; // audio clock regeneration packet
|
||
|
subpacket[0]<=audioRegenPacket;
|
||
|
subpacket[1]<=audioRegenPacket;
|
||
|
subpacket[2]<=audioRegenPacket;
|
||
|
subpacket[3]<=audioRegenPacket;
|
||
|
_timer <= _timer - CTS + 1;
|
||
|
end else begin
|
||
|
if (!oddLine) begin
|
||
|
packetHeader<=24'h0D0282; // infoframe AVI packet
|
||
|
// Byte0: Checksum (256-(S%256))%256
|
||
|
// Byte1: 10 = 0(Y1:Y0=0 RGB)(A0=1 active format valid)(B1:B0=00 No bar info)(S1:S0=00 No scan info)
|
||
|
// Byte2: 19 = (C1:C0=0 No colorimetry)(M1:M0=1 4:3)(R3:R0=9 4:3 center)
|
||
|
// Byte3: 00 = 0(SC1:SC0=0 No scaling)
|
||
|
// Byte4: 00 = 0(VIC6:VIC0=0 custom resolution)
|
||
|
// Byte5: 00 = 0(PR5:PR0=0 No repeation)
|
||
|
subpacket[0]<=56'h00000000191046;
|
||
|
subpacket[1]<=56'h00000000000000;
|
||
|
end else begin
|
||
|
packetHeader<=24'h0A0184; // infoframe audio packet
|
||
|
// Byte0: Checksum (256-(S%256))%256
|
||
|
// Byte1: 11 = (CT3:0=1 PCM)0(CC2:0=1 2ch)
|
||
|
// Byte2: 00 = 000(SF2:0=0 As stream)(SS1:0=0 As stream)
|
||
|
// Byte3: 00 = LPCM doesn't use this
|
||
|
// Byte4-5: 00 Multichannel only (>2ch)
|
||
|
subpacket[0]<=56'h00000000001160;
|
||
|
subpacket[1]<=56'h00000000000000;
|
||
|
end
|
||
|
_packet_ready <= 1;
|
||
|
end
|
||
|
|
||
|
if (audio_info) begin
|
||
|
packetHeader<=24'h0A0184; // infoframe audio packet
|
||
|
// Byte0: Checksum (256-(S%256))%256
|
||
|
// Byte1: 11 = (CT3:0=1 PCM)0(CC2:0=1 2ch)
|
||
|
// Byte2: 00 = 000(SF2:0=0 As stream)(SS1:0=0 As stream)
|
||
|
// Byte3: 00 = LPCM doesn't use this
|
||
|
// Byte4-5: 00 Multichannel only (>2ch)
|
||
|
subpacket[0]<=56'h00000000001160;
|
||
|
subpacket[1]<=56'h00000000000000;
|
||
|
subpacket[2]<=56'h00000000000000;
|
||
|
subpacket[3]<=56'h00000000000000;
|
||
|
end
|
||
|
_packet_ready <= 1;
|
||
|
end
|
||
|
|
||
|
if (video_info) begin
|
||
|
packetHeader<=24'h0D0282; // infoframe AVI packet
|
||
|
// Byte0: Checksum (256-(S%256))%256
|
||
|
// Byte1: 10 = 0(Y1:Y0=0 RGB)(A0=1 active format valid)(B1:B0=00 No bar info)(S1:S0=00 No scan info)
|
||
|
// Byte2: 19 = (C1:C0=0 No colorimetry)(M1:M0=1 4:3)(R3:R0=9 4:3 center)
|
||
|
// Byte3: 00 = 0(SC1:SC0=0 No scaling)
|
||
|
// Byte4: 00 = 0(VIC6:VIC0=0 custom resolution)
|
||
|
// Byte5: 00 = 0(PR5:PR0=0 No repeation)
|
||
|
subpacket[0]<=56'h00000000191046;
|
||
|
subpacket[1]<=56'h00000000000000;
|
||
|
subpacket[2]<=56'h00000000000000;
|
||
|
subpacket[3]<=56'h00000000000000;
|
||
|
_packet_ready <= 1;
|
||
|
end
|
||
|
|
||
|
end
|
||
|
endtask
|
||
|
|
||
| ... | ... | |
|
|
||
|
task SendPackets;
|
||
|
inout dataEnable;
|
||
|
inout _packet_sent;
|
||
|
begin
|
||
|
_packet_sent<=0;
|
||
|
if (counterX<32) begin
|
||
|
// Send first data packet (Infoframe or audio clock regen)
|
||
|
dataEnable<=1;
|
||
|
SendPacket(packetHeader, subpacket[0], subpacket[1], subpacket[2], subpacket[3], 1);
|
||
|
if (packet_needed & packet_ready) begin
|
||
|
dataEnable<=1;
|
||
|
SendPacket(packetHeader, subpacket[0], subpacket[1], subpacket[2], subpacket[3], 1);
|
||
|
end
|
||
|
if (counterX==31) begin
|
||
|
_packet_sent<=packet_needed&packet_ready&dataEnable;
|
||
|
end
|
||
|
end else if (counterX<64) begin
|
||
|
// Send second data packet (audio data)
|
||
|
dataEnable<=1;
|
||
|
SendPacket(audioPacketHeader, audioSubPacket[0], audioSubPacket[1], audioSubPacket[2], audioSubPacket[3], 0);
|
||
|
end else begin
|
||
|
dataEnable<=0;
|
||
| ... | ... | |
|
|
||
|
AudioGen();
|
||
|
|
||
|
packet_sent <= 1'b0;
|
||
|
audio_regen_needed <= 1'b0;
|
||
|
start_of_frame <= 1'b0;
|
||
|
|
||
|
// Send 2 packets each line
|
||
|
if(allowGeneration) begin
|
||
|
SendPackets(tercData);
|
||
|
SendPackets(tercData,packet_sent);
|
||
|
end else begin
|
||
|
tercData<=0;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
ctsTimer <= ctsTimer + 1;
|
||
|
|
||
| ... | ... | |
|
|
||
|
if(prevHSync != i_hSync) begin
|
||
|
if(firstHSyncChange) begin
|
||
|
InfoGen(ctsTimer);
|
||
|
InfoGen(ctsTimer,audio_regen_needed,packet_ready);
|
||
|
oddLine <= ! oddLine;
|
||
|
counterX <= 0;
|
||
|
allowGeneration <= 1;
|
||
| ... | ... | |
|
firstHSyncChange <= !firstHSyncChange;
|
||
|
end else
|
||
|
counterX <= counterX + 1;
|
||
|
|
||
|
if(prevVSync != i_vSync) begin
|
||
|
if(firstVSyncChange) begin
|
||
|
start_of_frame <= 1;
|
||
|
end
|
||
|
firstVSyncChange <= !firstVSyncChange;
|
||
|
end
|
||
|
|
||
|
prevBlank <= i_blank;
|
||
|
prevHSync <= i_hSync;
|
||
|
prevVSync <= i_vSync;
|
||
|
end
|
||
|
|
||
|
assign o_d0 = dataChannel0;
|
||
| eclaireXL_ITX/hdmi/infopacketstate.v | ||
|---|---|---|
|
module infopacketstate (
|
||
|
clock , // clock
|
||
|
reset , // Active high, syn reset
|
||
|
|
||
|
start_of_frame,
|
||
|
audio_regen_needed,
|
||
|
packet_sent,
|
||
|
|
||
|
audio_regen,
|
||
|
audio_info,
|
||
|
video_info,
|
||
|
packet_needed
|
||
|
);
|
||
|
//-------------Input Ports-----------------------------
|
||
|
input clock,reset,start_of_frame,audio_regen_needed,packet_sent;
|
||
|
//-------------Output Ports----------------------------
|
||
|
output audio_regen,audio_info,video_info,packet_needed;
|
||
|
//-------------Input ports Data Type-------------------
|
||
|
wire clock,reset,start_of_frame,audio_regen_needed,packet_sent;
|
||
|
//-------------Output Ports Data Type------------------
|
||
|
reg audio_regen,audio_info,video_info,packet_needed;
|
||
|
//-------------Internal Constants--------------------------
|
||
|
parameter SIZE = 5 ;
|
||
|
parameter CHOOSE = 2'b00,AUDIO_REGEN = 2'b01,AUDIO_INFO = 2'b10,VIDEO_INFO = 2'b11;
|
||
|
//-------------Internal Variables---------------------------
|
||
|
reg [SIZE-1:0] state ;// Seq part of the FSM
|
||
|
wire [SIZE-1:0] next_state ;// combo part of FSM
|
||
|
//----------Code startes Here------------------------
|
||
|
assign next_state = fsm_function(state,start_of_frame,audio_regen_needed,packet_sent);
|
||
|
//----------Function for Combo Logic-----------------
|
||
|
function [SIZE-1:0] fsm_function;
|
||
|
input [SIZE-1:0] state ;
|
||
|
input start_of_frame ;
|
||
|
input audio_regen_needed ;
|
||
|
input packet_sent ;
|
||
|
|
||
|
fsm_function[4] = start_of_frame | state[4]; //video_info
|
||
|
fsm_function[3] = start_of_frame | state[3]; //audio_info
|
||
|
fsm_function[2] = audio_regen_needed | state[2]; //audio_regen
|
||
|
fsm_function[1:0] = state[1:0];
|
||
|
|
||
|
case(state[1:0])
|
||
|
CHOOSE : if (state[2] == 1'b1) begin
|
||
|
fsm_function[1:0] = AUDIO_REGEN;;
|
||
|
end else if (state[3] == 1'b1) begin
|
||
|
fsm_function[1:0] = AUDIO_INFO;
|
||
|
end else if (state[4] == 1'b1) begin
|
||
|
fsm_function[1:0] = VIDEO_INFO;
|
||
|
end
|
||
|
AUDIO_REGEN : if (packet_sent == 1'b1) begin
|
||
|
fsm_function[1:0] = CHOOSE;
|
||
|
fsm_function[2] = 0;
|
||
|
end
|
||
|
AUDIO_INFO : if (packet_sent == 1'b1) begin
|
||
|
fsm_function[1:0] = CHOOSE;
|
||
|
fsm_function[3] = 0;
|
||
|
end
|
||
|
VIDEO_INFO : if (packet_sent == 1'b1) begin
|
||
|
fsm_function[1:0] = CHOOSE;
|
||
|
fsm_function[4] = 0;
|
||
|
end
|
||
|
default : fsm_function = CHOOSE;
|
||
|
endcase
|
||
|
endfunction
|
||
|
//----------Seq Logic-----------------------------
|
||
|
always @ (posedge clock)
|
||
|
begin : FSM_SEQ
|
||
|
if (reset == 1'b1) begin
|
||
|
state <= #1 CHOOSE;
|
||
|
end else begin
|
||
|
state <= #1 next_state;
|
||
|
end
|
||
|
end
|
||
|
//----------Output Logic-----------------------------
|
||
|
always @ (posedge clock)
|
||
|
begin : OUTPUT_LOGIC
|
||
|
if (reset == 1'b1) begin
|
||
|
audio_regen <= #1 1'b0;
|
||
|
video_info <= #1 1'b0;
|
||
|
audio_info <= #1 1'b0;
|
||
|
packet_needed <= #1 1'b0;
|
||
|
end
|
||
|
else begin
|
||
|
case(state[1:0])
|
||
|
CHOOSE : begin
|
||
|
audio_regen <= #1 1'b0;
|
||
|
video_info <= #1 1'b0;
|
||
|
audio_info <= #1 1'b0;
|
||
|
packet_needed <= #1 1'b0;
|
||
|
end
|
||
|
AUDIO_REGEN : begin
|
||
|
audio_regen <= #1 1'b1;
|
||
|
video_info <= #1 1'b0;
|
||
|
audio_info <= #1 1'b0;
|
||
|
packet_needed <= #1 1'b1;
|
||
|
end
|
||
|
AUDIO_INFO : begin
|
||
|
audio_regen <= #1 1'b0;
|
||
|
video_info <= #1 1'b0;
|
||
|
audio_info <= #1 1'b1;
|
||
|
packet_needed <= #1 1'b1;
|
||
|
end
|
||
|
VIDEO_INFO : begin
|
||
|
audio_regen <= #1 1'b0;
|
||
|
video_info <= #1 1'b1;
|
||
|
audio_info <= #1 1'b0;
|
||
|
packet_needed <= #1 1'b1;
|
||
|
end
|
||
|
default : begin
|
||
|
audio_regen <= #1 1'b0;
|
||
|
video_info <= #1 1'b0;
|
||
|
audio_info <= #1 1'b0;
|
||
|
packet_needed <= #1 1'b0;
|
||
|
end
|
||
|
endcase
|
||
|
end
|
||
|
end // End Of Block OUTPUT_LOGIC
|
||
|
|
||
|
endmodule // End of Module arbiter
|
||
| eclaireXL_ITX/hdmi/scandoubler_hdmi.vhdl | ||
|---|---|---|
|
hdmiav_inst : entity work.hdmi
|
||
|
port map (
|
||
|
I_CLK_PIXEL => clk_pixel_in,
|
||
|
I_RESET => not(reset_n),
|
||
|
I_AUDIO_PCM_L => audio_left_reg2,
|
||
|
I_AUDIO_PCM_R => audio_right_reg2,
|
||
|
I_HSYNC => hsync_reg,
|
||
Send fewer info packets, spec expects 1/frame