Revision 951
Added by markw almost 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,
|
Also available in: Unified diff
Send fewer info packets, spec expects 1/frame