Moved hardcoded numbers to parameters, improved newline behaviour, tried to get 1080p60 to work
This commit is contained in:
parent
5d5fef95df
commit
9b5fd29244
50
HDMI.alp
50
HDMI.alp
|
@ -1,25 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="HDMI" board="Mojo" language="Verilog" version="2">
|
||||
<files>
|
||||
<component>cclk_detector.luc</component>
|
||||
<component>simple_dual_ram.v</component>
|
||||
<component>async_fifo.luc</component>
|
||||
<component>uart_rx.luc</component>
|
||||
<component>fifo_2x_reducer.luc</component>
|
||||
<component>tmds_encoder.luc</component>
|
||||
<component>spi_slave.luc</component>
|
||||
<src top="true">mojo_top.v</src>
|
||||
<component>serdes_n_to_1.luc</component>
|
||||
<component>uart_tx.luc</component>
|
||||
<component>dvi_encoder.luc</component>
|
||||
<component>hdmi_encoder.luc</component>
|
||||
<src>sram.v</src>
|
||||
<component>dvi_globals.luc</component>
|
||||
<component>avr_interface.luc</component>
|
||||
<constraint lib="true">hdmi.ucf</constraint>
|
||||
<constraint lib="true">mojo.ucf</constraint>
|
||||
<core name="clk_wiz_v3_6">
|
||||
<src>..\clk_wiz_v3_6.v</src>
|
||||
</core>
|
||||
</files>
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="HDMI" board="Mojo" language="Verilog" version="2">
|
||||
<files>
|
||||
<src>hdmi_encoder.luc</src>
|
||||
<src top="true">mojo_top.v</src>
|
||||
<component>uart_rx.luc</component>
|
||||
<src>sram.v</src>
|
||||
<component>fifo_2x_reducer.luc</component>
|
||||
<component>dvi_globals.luc</component>
|
||||
<component>avr_interface.luc</component>
|
||||
<component>dvi_encoder.luc</component>
|
||||
<component>spi_slave.luc</component>
|
||||
<component>uart_tx.luc</component>
|
||||
<component>serdes_n_to_1.luc</component>
|
||||
<component>simple_dual_ram.v</component>
|
||||
<component>async_fifo.luc</component>
|
||||
<component>cclk_detector.luc</component>
|
||||
<component>tmds_encoder.luc</component>
|
||||
<constraint lib="true">mojo.ucf</constraint>
|
||||
<constraint lib="true">hdmi.ucf</constraint>
|
||||
<core name="clk_wiz_v3_6">
|
||||
<src>..\clk_wiz_v3_6.v</src>
|
||||
</core>
|
||||
</files>
|
||||
</project>
|
||||
|
|
115
source/hdmi_encoder.luc
Normal file
115
source/hdmi_encoder.luc
Normal file
|
@ -0,0 +1,115 @@
|
|||
/******************************************************************************
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Alchitry
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
module hdmi_encoder #(
|
||||
PCLK_DIV = 1 : PCLK_DIV >= 1 && PCLK_DIV < 12,
|
||||
Y_RES = 720 : Y_RES > 0,
|
||||
X_RES = 1280 : X_RES > 0,
|
||||
Y_FRAME = 750 : Y_FRAME >= Y_RES + 15,
|
||||
X_FRAME = 1667 : X_FRAME >= X_RES + 30
|
||||
)(
|
||||
input clk, // clock
|
||||
input rst, // reset
|
||||
output pclk,
|
||||
output tmds[4],
|
||||
output tmdsb[4],
|
||||
output active,
|
||||
output x[12],
|
||||
output y[11],
|
||||
input red[8],
|
||||
input green[8],
|
||||
input blue[8]
|
||||
) {
|
||||
|
||||
sig clkfbin;
|
||||
|
||||
xil_PLL_BASE pll_oserdes (
|
||||
#CLKIN_PERIOD(10),
|
||||
#CLKFBOUT_MULT(10), //set VCO to 10x of CLKIN
|
||||
#CLKOUT0_DIVIDE(1 * PCLK_DIV),
|
||||
#CLKOUT1_DIVIDE(10 * PCLK_DIV),
|
||||
#CLKOUT2_DIVIDE(5 * PCLK_DIV),
|
||||
#COMPENSATION("SOURCE_SYNCHRONOUS"),
|
||||
.CLKFBIN(clkfbin),
|
||||
.CLKIN(clk),
|
||||
.RST(0)
|
||||
);
|
||||
|
||||
xil_BUFG clkfb_buf (.I(pll_oserdes.CLKFBOUT));
|
||||
always clkfbin = clkfb_buf.O;
|
||||
|
||||
xil_BUFG pclkx2_buf (.I(pll_oserdes.CLKOUT2));
|
||||
|
||||
xil_BUFG pclk_buf(.I(pll_oserdes.CLKOUT1));
|
||||
|
||||
xil_BUFPLL ioclk_buf (
|
||||
#DIVIDE(5),
|
||||
.PLLIN(pll_oserdes.CLKOUT0),
|
||||
.GCLK(pclkx2_buf.O),
|
||||
.LOCKED(pll_oserdes.LOCKED)
|
||||
);
|
||||
|
||||
.clk(pclk_buf.O) {
|
||||
.rst(rst) {
|
||||
dff ctrX[12];
|
||||
dff ctrY[11];
|
||||
}
|
||||
}
|
||||
|
||||
sig hSync, vSync, drawArea;
|
||||
|
||||
dvi_encoder dvi (
|
||||
.pclk(pclk_buf.O),
|
||||
.pclkx2(pclkx2_buf.O),
|
||||
.pclkx10(ioclk_buf.IOCLK),
|
||||
.strobe(ioclk_buf.SERDESSTROBE),
|
||||
.rst(~ioclk_buf.LOCK),
|
||||
.blue(blue),
|
||||
.green(green),
|
||||
.red(red),
|
||||
.hsync(hSync),
|
||||
.vsync(vSync),
|
||||
.de(drawArea)
|
||||
);
|
||||
|
||||
|
||||
always {
|
||||
ctrX.d = (ctrX.q == X_FRAME-1) ? 0 : ctrX.q + 1;
|
||||
if (ctrX.q == X_FRAME-1)
|
||||
ctrY.d = (ctrY.q == Y_FRAME-1) ? 0 : ctrY.q + 1;
|
||||
pclk = pclk_buf.O;
|
||||
hSync = (ctrX.q >= X_RES + 10) && (ctrX.q < X_RES + 20);
|
||||
vSync = (ctrY.q >= Y_RES + 10) && (ctrY.q < Y_RES + 12);
|
||||
drawArea = (ctrX.q < X_RES) && (ctrY.q < Y_RES);
|
||||
|
||||
active = drawArea;
|
||||
x = ctrX.q;
|
||||
y = ctrY.q;
|
||||
|
||||
tmds = dvi.tmds;
|
||||
tmdsb = dvi.tmdsb;
|
||||
}
|
||||
}
|
|
@ -27,8 +27,8 @@ module mojo_top(
|
|||
wire hdmi_clk;
|
||||
|
||||
reg[7:0] hdmired, hdmigreen, hdmiblue;
|
||||
wire[10:0] hdmix;
|
||||
wire[9:0] hdmiy;
|
||||
wire[11:0] hdmix;
|
||||
wire[10:0] hdmiy;
|
||||
|
||||
reg[7:0] frame_q, frame_d;
|
||||
|
||||
|
@ -36,8 +36,18 @@ module mojo_top(
|
|||
.CLK_IN1(clk),
|
||||
.CLK_OUT1(hdmi_clk)
|
||||
);
|
||||
|
||||
localparam SCALE = 2;
|
||||
localparam WIDTH = 1280;
|
||||
localparam HEIGHT = 720;
|
||||
// localparam WIDTH = 1920;
|
||||
// localparam HEIGHT = 1080;
|
||||
localparam CHAR_HMAX = WIDTH / (SCALE*8);
|
||||
localparam CHAR_VMAX = HEIGHT / (SCALE*8);
|
||||
|
||||
hdmi_encoder hdmi(
|
||||
// @todo 1080p30 does not work for some reason (already extended number of bits)
|
||||
hdmi_encoder #(.Y_RES(HEIGHT), .X_RES(WIDTH), .Y_FRAME(HEIGHT+30), .X_FRAME(WIDTH+387)) hdmi(
|
||||
// hdmi_encoder #(.Y_RES(HEIGHT), .X_RES(WIDTH), .Y_FRAME(HEIGHT+45), .X_FRAME(WIDTH+303)) hdmi(
|
||||
.clk(hdmi_clk),
|
||||
.rst(rst),
|
||||
.tmds(hdmi1_tmds),
|
||||
|
@ -147,13 +157,11 @@ module mojo_top(
|
|||
assign char_data[93] = 30'h610C46; // }
|
||||
assign char_data[94] = 30'hAA0000; // ~
|
||||
|
||||
reg[11:0] char_index_q, char_index_d;
|
||||
reg[13:0] char_index_q, char_index_d;
|
||||
|
||||
reg[10:0] charx;
|
||||
reg[9:0] chary;
|
||||
|
||||
localparam SCALE = 2;
|
||||
|
||||
reg[7:0] tx_data;
|
||||
reg new_tx_data;
|
||||
wire tx_busy;
|
||||
|
@ -185,11 +193,11 @@ module mojo_top(
|
|||
.new_rx_data(new_rx_data)
|
||||
);
|
||||
|
||||
reg [11:0] addr_q, addr_d;
|
||||
reg [13:0] addr_q, addr_d;
|
||||
reg[7:0] write_data;
|
||||
reg write_enable;
|
||||
wire[7:0] sram_read_data;
|
||||
sram #(.SIZE(8), .DEPTH(3600)) sram(
|
||||
sram #(.SIZE(8), .DEPTH(CHAR_HMAX*CHAR_VMAX)) sram(
|
||||
.clk(hdmi_clk),
|
||||
.read_address(char_index_q),
|
||||
.write_address(addr_q),
|
||||
|
@ -199,23 +207,26 @@ module mojo_top(
|
|||
);
|
||||
|
||||
always @(*) begin
|
||||
hdmired = 1'h28;
|
||||
hdmigreen = 1'h28;
|
||||
hdmiblue = 1'h28;
|
||||
hdmired = 1'b0;
|
||||
hdmigreen = 1'b0;
|
||||
hdmiblue = 1'b0;
|
||||
|
||||
charx = (hdmix >> (SCALE-1)) % 8;
|
||||
// @todo For some reason we need a -1 here, otherwise it looks weird with
|
||||
// SCALE = 1
|
||||
// Need to figure that out, something to do with wrap around
|
||||
charx = ((hdmix >> (SCALE-1)) - 1) % 8;
|
||||
chary = (hdmiy >> (SCALE-1)) % 8;
|
||||
|
||||
if (char_index_q < 3600 && charx > 0 && charx < 6 && chary > 1 && char_data[sram_read_data][29 - (charx - 1) - 5*(chary - 2)] == 1) begin
|
||||
hdmired = 8'hEB;
|
||||
hdmigreen = 8'hDB;
|
||||
hdmiblue = 8'hB2;
|
||||
if (charx > 0 && charx < 6 && chary > 1 && char_data[sram_read_data][29 - (charx - 1) - 5*(chary - 2)] == 1) begin
|
||||
hdmired = 8'hFF;
|
||||
hdmigreen = 8'hFF;
|
||||
hdmiblue = 8'hFF;
|
||||
end
|
||||
|
||||
frame_d = frame_q;
|
||||
char_index_d = ((hdmix >> (SCALE+2)) + 80*(hdmiy >> (SCALE+2)));
|
||||
char_index_d = ((hdmix >> (SCALE+2)) + CHAR_HMAX*(hdmiy >> (SCALE+2)));
|
||||
|
||||
if (hdmix == 1279 && hdmiy == 719) begin
|
||||
if (hdmix == WIDTH-1 && hdmiy == HEIGHT-1) begin
|
||||
frame_d = frame_q + 1'b1;
|
||||
end
|
||||
|
||||
|
@ -228,9 +239,8 @@ module mojo_top(
|
|||
tx_data = rx_data;
|
||||
|
||||
if (rx_data == "\r") begin
|
||||
addr_d = addr_q - (addr_q % 80);
|
||||
end else if (rx_data == "\n") begin
|
||||
addr_d = addr_q + 80;
|
||||
addr_d = addr_q - (addr_q % CHAR_HMAX) + CHAR_HMAX;
|
||||
end else if (rx_data == 8) begin
|
||||
addr_d = addr_q - 1'b1;
|
||||
end else begin
|
||||
|
|
Reference in New Issue
Block a user