mirror of
https://github.com/MiSTer-devel/MacPlus_MiSTer.git
synced 2024-11-27 02:49:32 +00:00
Update sys. HV-Integer scale.
This commit is contained in:
parent
6e539eba92
commit
7d22fc77e8
23
MacPlus.sv
23
MacPlus.sv
@ -39,8 +39,9 @@ module emu
|
||||
output CE_PIXEL,
|
||||
|
||||
//Video aspect ratio for HDMI. Most retro systems have ratio 4:3.
|
||||
output [11:0] VIDEO_ARX,
|
||||
output [11:0] VIDEO_ARY,
|
||||
//if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio.
|
||||
output [12:0] VIDEO_ARX,
|
||||
output [12:0] VIDEO_ARY,
|
||||
|
||||
output [7:0] VGA_R,
|
||||
output [7:0] VGA_G,
|
||||
@ -52,6 +53,9 @@ module emu
|
||||
output [1:0] VGA_SL,
|
||||
output VGA_SCALER, // Force VGA scaler
|
||||
|
||||
input [11:0] HDMI_WIDTH,
|
||||
input [11:0] HDMI_HEIGHT,
|
||||
|
||||
`ifdef USE_FB
|
||||
// Use framebuffer in DDRAM (USE_FB=1 in qsf)
|
||||
// FB_FORMAT:
|
||||
@ -182,9 +186,18 @@ assign BUTTONS = 0;
|
||||
assign VGA_SCALER= 0;
|
||||
|
||||
wire [1:0] ar = status[8:7];
|
||||
video_freak video_freak
|
||||
(
|
||||
.*,
|
||||
.VGA_DE_IN(VGA_DE),
|
||||
.VGA_DE(),
|
||||
|
||||
assign VIDEO_ARX = (!ar) ? 12'd4 : (ar - 1'd1);
|
||||
assign VIDEO_ARY = (!ar) ? 12'd3 : 12'd0;
|
||||
.ARX((!ar) ? 12'd4 : (ar - 1'd1)),
|
||||
.ARY((!ar) ? 12'd3 : 12'd0),
|
||||
.CROP_SIZE(0),
|
||||
.CROP_OFF(0),
|
||||
.SCALE(status[12:11])
|
||||
);
|
||||
|
||||
`include "build_id.v"
|
||||
localparam CONF_STR = {
|
||||
@ -196,6 +209,8 @@ localparam CONF_STR = {
|
||||
"S0,VHD,Mount HDD;",
|
||||
"-;",
|
||||
"O78,Aspect ratio,Original,Full Screen,[ARC1],[ARC2];",
|
||||
"OBC,Scale,Normal,V-Integer,Narrower HV-Integer,Wider HV-Integer;",
|
||||
"-;",
|
||||
"O9A,Memory,512KB,1MB,4MB;",
|
||||
"O5,Speed,Normal,Turbo;",
|
||||
"-;",
|
||||
|
@ -112,9 +112,9 @@ wire scandoubler = fx || forced_scandoubler;
|
||||
|
||||
video_mixer #(.LINE_LENGTH(WIDTH+4), .HALF_DEPTH(DW!=24), .GAMMA(GAMMA)) video_mixer
|
||||
(
|
||||
.clk_vid(CLK_VIDEO),
|
||||
.CLK_VIDEO(CLK_VIDEO),
|
||||
.ce_pix(CE),
|
||||
.ce_pix_out(CE_PIXEL),
|
||||
.CE_PIXEL(CE_PIXEL),
|
||||
|
||||
.scandoubler(scandoubler),
|
||||
.hq2x(fx==1),
|
||||
|
@ -429,7 +429,7 @@ ARCHITECTURE rtl OF ascal IS
|
||||
SIGNAL o_readdataack,o_readdataack_sync,o_readdataack_sync2 : std_logic;
|
||||
SIGNAL o_copyv : unsigned(0 TO 8);
|
||||
SIGNAL o_adrs : unsigned(31 DOWNTO 0); -- Avalon address
|
||||
SIGNAL o_adrs_pre : natural RANGE 0 TO 2**23-1;
|
||||
SIGNAL o_adrs_pre : natural RANGE 0 TO 2**24-1;
|
||||
SIGNAL o_stride : unsigned(13 DOWNTO 0);
|
||||
SIGNAL o_adrsa,o_adrsb,o_rline : std_logic;
|
||||
SIGNAL o_ad,o_ad1,o_ad2,o_ad3 : natural RANGE 0 TO 2*BLEN-1;
|
||||
@ -1519,7 +1519,7 @@ BEGIN
|
||||
avl_read_sync<=o_read; -- <ASYNC>
|
||||
avl_read_sync2<=avl_read_sync;
|
||||
avl_read_pulse<=avl_read_sync XOR avl_read_sync2;
|
||||
avl_radrs <=o_adrs AND (RAMSIZE - 1); -- <ASYNC>
|
||||
avl_radrs <=o_adrs; -- <ASYNC>
|
||||
avl_rline <=o_rline; -- <ASYNC>
|
||||
|
||||
--------------------------------------------
|
||||
|
250
sys/f2sdram_safe_terminator.sv
Normal file
250
sys/f2sdram_safe_terminator.sv
Normal file
@ -0,0 +1,250 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// f2sdram_safe_terminator for MiSTer platform
|
||||
//
|
||||
// ============================================================================
|
||||
// Copyright (c) 2021 bellwood420
|
||||
//
|
||||
// Background:
|
||||
//
|
||||
// Terminating a transaction of burst writing(/reading) in its midstream
|
||||
// seems to cause an illegal state to f2sdram interface.
|
||||
//
|
||||
// Forced reset request that occurs when loading other core is inevitable.
|
||||
//
|
||||
// So if it happens exactly within the transaction period,
|
||||
// unexpected issues with accessing to f2sdram interface will be caused
|
||||
// in next loaded core.
|
||||
//
|
||||
// It seems that only way to reset broken f2sdram interface is to reset
|
||||
// whole SDRAM Controller Subsystem from HPS via permodrst register
|
||||
// in Reset Manager.
|
||||
// But it cannot be done safely while Linux is running.
|
||||
// It is usually done when cold or warm reset is issued in HPS.
|
||||
//
|
||||
// Main_MiSTer is issuing reset for FPGA <> HPS bridges
|
||||
// via brgmodrst register in Reset Manager when loading rbf.
|
||||
// But it has no effect on f2sdram interface.
|
||||
// f2sdram interface seems to belong to SDRAM Controller Subsystem
|
||||
// rather than FPGA-to-HPS bridge.
|
||||
//
|
||||
// Main_MiSTer is also trying to issuing reset for f2sdram ports
|
||||
// via fpgaportrst register in SDRAM Controller Subsystem when loading rbf.
|
||||
// But according to the Intel's document, fpgaportrst register can be
|
||||
// used to stretch the port reset.
|
||||
// It seems that it cannot be used to assert the port reset.
|
||||
//
|
||||
// According to the Intel's document, there seems to be a reset port on
|
||||
// Avalon-MM slave interface, but it cannot be found in Qsys generated HDL.
|
||||
//
|
||||
// To conclude, the only thing FPGA can do is not to break the transaction.
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//
|
||||
// Purpose:
|
||||
// To prevent the issue, this module completes ongoing transaction
|
||||
// on behalf of user logic, when reset is asserted.
|
||||
//
|
||||
// Usage:
|
||||
// Insert this module into the bus line between
|
||||
// f2sdram (Avalon-MM slave) and user logic (Avalon-MM master).
|
||||
//
|
||||
// Notice:
|
||||
// Asynchronous reset request is not supported.
|
||||
// Please feed reset request synchronized to clock.
|
||||
//
|
||||
module f2sdram_safe_terminator #(
|
||||
parameter DATA_WIDTH = 64,
|
||||
parameter BURSTCOUNT_WIDTH = 8
|
||||
) (
|
||||
// clk should be the same as one provided to f2sdram port
|
||||
// clk should not be stop when reset is asserted
|
||||
input clk,
|
||||
// rst_req_sync should be synchronized to clk
|
||||
// Asynchronous reset request is not supported
|
||||
input rst_req_sync,
|
||||
|
||||
// Master port: connecting to Alavon-MM slave(f2sdram)
|
||||
input waitrequest_master,
|
||||
output [BURSTCOUNT_WIDTH-1:0] burstcount_master,
|
||||
output [ADDRESS_WITDH-1:0] address_master,
|
||||
input [DATA_WIDTH-1:0] readdata_master,
|
||||
input readdatavalid_master,
|
||||
output read_master,
|
||||
output [DATA_WIDTH-1:0] writedata_master,
|
||||
output [BYTEENABLE_WIDTH-1:0] byteenable_master,
|
||||
output write_master,
|
||||
|
||||
// Slave port: connecting to Alavon-MM master(user logic)
|
||||
output waitrequest_slave,
|
||||
input [BURSTCOUNT_WIDTH-1:0] burstcount_slave,
|
||||
input [ADDRESS_WITDH-1:0] address_slave,
|
||||
output [DATA_WIDTH-1:0] readdata_slave,
|
||||
output readdatavalid_slave,
|
||||
input read_slave,
|
||||
input [DATA_WIDTH-1:0] writedata_slave,
|
||||
input [BYTEENABLE_WIDTH-1:0] byteenable_slave,
|
||||
input write_slave
|
||||
);
|
||||
|
||||
localparam BYTEENABLE_WIDTH = DATA_WIDTH/8;
|
||||
localparam ADDRESS_WITDH = 32-$clog2(BYTEENABLE_WIDTH);
|
||||
|
||||
/*
|
||||
* Capture init reset deaseert
|
||||
*/
|
||||
reg init_reset_deasserted = 1'b0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_req_sync) begin
|
||||
init_reset_deasserted <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* Lock stage
|
||||
*/
|
||||
reg lock_stage = 1'b0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst_req_sync) begin
|
||||
// Reset assert
|
||||
if (init_reset_deasserted) begin
|
||||
lock_stage <= 1'b1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// Reset deassert
|
||||
lock_stage <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* Write burst transaction observer
|
||||
*/
|
||||
reg state_write = 1'b0;
|
||||
wire next_state_write;
|
||||
|
||||
wire burst_write_start = !state_write && next_state_write;
|
||||
wire valid_write_data = state_write && !waitrequest_master;
|
||||
wire burst_write_end = state_write && (write_burstcounter == write_burstcount_latch - 1'd1);
|
||||
wire valid_non_burst_write = !state_write && write_slave && (burstcount_slave == 1) && !waitrequest_master;
|
||||
|
||||
reg [BURSTCOUNT_WIDTH-1:0] write_burstcounter = 0;
|
||||
reg [BURSTCOUNT_WIDTH-1:0] write_burstcount_latch = 0;
|
||||
reg [ADDRESS_WITDH-1:0] write_address_latch = 0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
state_write <= next_state_write;
|
||||
|
||||
if (burst_write_start) begin
|
||||
write_burstcounter <= waitrequest_master ? 1'd0 : 1'd1;
|
||||
write_burstcount_latch <= burstcount_slave;
|
||||
write_address_latch <= address_slave;
|
||||
end
|
||||
else if (valid_write_data) begin
|
||||
write_burstcounter <= write_burstcounter + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
if (!state_write) begin
|
||||
if (valid_non_burst_write)
|
||||
next_state_write = 1'b0;
|
||||
else if (write_slave)
|
||||
next_state_write = 1'b1;
|
||||
else
|
||||
next_state_write = 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (burst_write_end)
|
||||
next_state_write = 1'b0;
|
||||
else
|
||||
next_state_write = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
reg [BURSTCOUNT_WIDTH-1:0] write_terminate_counter = 0;
|
||||
reg [BURSTCOUNT_WIDTH-1:0] burstcount_latch = 0;
|
||||
reg [ADDRESS_WITDH-1:0] address_latch = 0;
|
||||
|
||||
reg terminating = 0;
|
||||
reg read_terminating = 0;
|
||||
reg write_terminating = 0;
|
||||
|
||||
wire on_write_transaction = state_write && next_state_write;
|
||||
wire on_start_write_transaction = !state_write && next_state_write;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst_req_sync) begin
|
||||
// Reset assert
|
||||
if (init_reset_deasserted) begin
|
||||
if (!lock_stage) begin
|
||||
// Even not knowing reading is in progress or not,
|
||||
// if it is in progress, it will finish at some point, and no need to do anything.
|
||||
// Assume that reading is in progress when we are not on write transaction.
|
||||
burstcount_latch <= burstcount_slave;
|
||||
address_latch <= address_slave;
|
||||
terminating <= 1;
|
||||
|
||||
if (on_write_transaction) begin
|
||||
write_terminating <= 1;
|
||||
burstcount_latch <= write_burstcount_latch;
|
||||
address_latch <= write_address_latch;
|
||||
write_terminate_counter <= waitrequest_master ? write_burstcounter : write_burstcounter + 1'd1;
|
||||
end
|
||||
else if (on_start_write_transaction) begin
|
||||
if (!valid_non_burst_write) begin
|
||||
write_terminating <= 1;
|
||||
write_terminate_counter <= waitrequest_master ? 1'd0 : 1'd1;
|
||||
end
|
||||
end
|
||||
else if (read_slave && waitrequest_master) begin
|
||||
// Need to keep read signal, burstcount and address until waitrequest_master deasserted
|
||||
read_terminating <= 1;
|
||||
end
|
||||
end
|
||||
else if (!waitrequest_master) begin
|
||||
read_terminating <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// Reset deassert
|
||||
if (!write_terminating) terminating <= 0;
|
||||
read_terminating <= 0;
|
||||
end
|
||||
|
||||
if (write_terminating) begin
|
||||
// Continue write transaction until the end
|
||||
if (!waitrequest_master) write_terminate_counter <= write_terminate_counter + 1'd1;
|
||||
if (write_terminate_counter == burstcount_latch - 1'd1) write_terminating <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* Bus mux depending on the stage.
|
||||
*/
|
||||
always_comb begin
|
||||
if (terminating) begin
|
||||
burstcount_master = burstcount_latch;
|
||||
address_master = address_latch;
|
||||
read_master = read_terminating;
|
||||
write_master = write_terminating;
|
||||
byteenable_master = 0;
|
||||
end
|
||||
else begin
|
||||
burstcount_master = burstcount_slave;
|
||||
address_master = address_slave;
|
||||
read_master = read_slave;
|
||||
byteenable_master = byteenable_slave;
|
||||
write_master = write_slave;
|
||||
end
|
||||
end
|
||||
|
||||
// Just passing master <-> slave
|
||||
assign writedata_master = writedata_slave;
|
||||
assign readdata_slave = readdata_master;
|
||||
assign readdatavalid_slave = readdatavalid_master;
|
||||
assign waitrequest_slave = waitrequest_master;
|
||||
|
||||
endmodule
|
19
sys/i2c.v
19
sys/i2c.v
@ -37,13 +37,23 @@ always @(posedge CLK) begin
|
||||
end
|
||||
end
|
||||
|
||||
assign I2C_SCL = SCLK | I2C_CLOCK;
|
||||
assign I2C_SCL = (SCLK | I2C_CLOCK) ? 1'bZ : 1'b0;
|
||||
assign I2C_SDA = SDO[3] ? 1'bz : 1'b0;
|
||||
|
||||
reg SCLK = 1;
|
||||
reg [3:0] SDO = 4'b1111;
|
||||
reg SCLK;
|
||||
reg [3:0] SDO;
|
||||
reg [0:7] rdata;
|
||||
|
||||
reg [5:0] SD_COUNTER;
|
||||
reg [0:31] SD;
|
||||
|
||||
initial begin
|
||||
SD_COUNTER = 'b111111;
|
||||
SD = 'hFFFF;
|
||||
SCLK = 1;
|
||||
SDO = 4'b1111;
|
||||
end
|
||||
|
||||
assign I2C_RDATA = rdata;
|
||||
|
||||
always @(posedge CLK) begin
|
||||
@ -51,9 +61,6 @@ always @(posedge CLK) begin
|
||||
reg old_st;
|
||||
reg rd,len;
|
||||
|
||||
reg [5:0] SD_COUNTER = 'b111111;
|
||||
reg [0:31] SD;
|
||||
|
||||
old_clk <= I2C_CLOCK;
|
||||
old_st <= START;
|
||||
|
||||
|
109
sys/math.sv
Normal file
109
sys/math.sv
Normal file
@ -0,0 +1,109 @@
|
||||
|
||||
// result = num/div
|
||||
module sys_udiv
|
||||
#(
|
||||
parameter NB_NUM,
|
||||
parameter NB_DIV
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input start,
|
||||
output busy,
|
||||
|
||||
input [NB_NUM-1:0] num,
|
||||
input [NB_DIV-1:0] div,
|
||||
output reg [NB_NUM-1:0] result,
|
||||
output reg [NB_DIV-1:0] remainder
|
||||
);
|
||||
|
||||
reg run;
|
||||
assign busy = run;
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg [5:0] cpt;
|
||||
reg [NB_NUM+NB_DIV+1:0] rem;
|
||||
|
||||
if (start) begin
|
||||
cpt <= 0;
|
||||
run <= 1;
|
||||
rem <= num;
|
||||
end
|
||||
else if (run) begin
|
||||
cpt <= cpt + 1'd1;
|
||||
run <= (cpt != NB_NUM + 1'd1);
|
||||
remainder <= rem[NB_NUM+NB_DIV:NB_NUM+1];
|
||||
if (!rem[NB_DIV + NB_NUM + 1'd1])
|
||||
rem <= {rem[NB_DIV+NB_NUM:0] - (div << NB_NUM),1'b0};
|
||||
else
|
||||
rem <= {rem[NB_DIV+NB_NUM:0] + (div << NB_NUM),1'b0};
|
||||
result <= {result[NB_NUM-2:0], !rem[NB_DIV + NB_NUM + 1'd1]};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
// result = mul1*mul2
|
||||
module sys_umul
|
||||
#(
|
||||
parameter NB_MUL1,
|
||||
parameter NB_MUL2
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input start,
|
||||
output busy,
|
||||
|
||||
input [NB_MUL1-1:0] mul1,
|
||||
input [NB_MUL2-1:0] mul2,
|
||||
output reg [NB_MUL1+NB_MUL2-1:0] result
|
||||
);
|
||||
|
||||
reg run;
|
||||
assign busy = run;
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg [NB_MUL1+NB_MUL2-1:0] add;
|
||||
reg [NB_MUL2-1:0] map;
|
||||
|
||||
if (start) begin
|
||||
run <= 1;
|
||||
result <= 0;
|
||||
add <= mul1;
|
||||
map <= mul2;
|
||||
end
|
||||
else if (run) begin
|
||||
if(!map) run <= 0;
|
||||
if(map[0]) result <= result + add;
|
||||
add <= add << 1;
|
||||
map <= map >> 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
// result = (mul1*mul2)/div
|
||||
module sys_umuldiv
|
||||
#(
|
||||
parameter NB_MUL1,
|
||||
parameter NB_MUL2,
|
||||
parameter NB_DIV
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input start,
|
||||
output busy,
|
||||
|
||||
input [NB_MUL1-1:0] mul1,
|
||||
input [NB_MUL2-1:0] mul2,
|
||||
input [NB_DIV-1:0] div,
|
||||
output [NB_MUL1+NB_MUL2-1:0] result,
|
||||
output [NB_DIV-1:0] remainder
|
||||
);
|
||||
|
||||
wire mul_run;
|
||||
wire [NB_MUL1+NB_MUL2-1:0] mul_res;
|
||||
sys_umul #(NB_MUL1,NB_MUL2) umul(clk,start,mul_run,mul1,mul2,mul_res);
|
||||
|
||||
sys_udiv #(NB_MUL1+NB_MUL2,NB_DIV) udiv(clk,start|mul_run,busy,mul_res,div,result,remainder);
|
||||
|
||||
endmodule
|
@ -2,7 +2,7 @@
|
||||
// scandoubler.v
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
// Copyright (c) 2017-2019 Sorgelig
|
||||
// Copyright (c) 2017-2021 Alexey Melnikov
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
@ -23,23 +23,20 @@ module scandoubler #(parameter LENGTH, parameter HALF_DEPTH)
|
||||
(
|
||||
// system interface
|
||||
input clk_vid,
|
||||
input ce_pix,
|
||||
output ce_pix_out,
|
||||
|
||||
input hq2x,
|
||||
|
||||
// shifter video interface
|
||||
input ce_pix,
|
||||
input hs_in,
|
||||
input vs_in,
|
||||
input hb_in,
|
||||
input vb_in,
|
||||
|
||||
input [DWIDTH:0] r_in,
|
||||
input [DWIDTH:0] g_in,
|
||||
input [DWIDTH:0] b_in,
|
||||
input mono,
|
||||
|
||||
// output interface
|
||||
output ce_pix_out,
|
||||
output reg hs_out,
|
||||
output vs_out,
|
||||
output hb_out,
|
||||
@ -109,7 +106,6 @@ Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x
|
||||
|
||||
.ce_in(ce_x4i),
|
||||
.inputpixel({b_d,g_d,r_d}),
|
||||
.mono(mono),
|
||||
.disable_hq2x(~hq2x),
|
||||
.reset_frame(vb_in),
|
||||
.reset_line(req_line_reset),
|
||||
|
27
sys/spdif.v
27
sys/spdif.v
@ -67,7 +67,7 @@ reg spdif_out_q;
|
||||
|
||||
reg [5:0] parity_count_q;
|
||||
|
||||
reg channel_status_bit;
|
||||
reg channel_status_bit_q;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Subframe Counter
|
||||
@ -144,19 +144,20 @@ assign subframe_w[28] = 1'b0; // Valid
|
||||
assign subframe_w[29] = 1'b0;
|
||||
|
||||
// Timeslots 30 = Channel status bit
|
||||
assign subframe_w[30] = channel_status_bit ; //was constant 1'b0 enabling copy-bit;
|
||||
assign subframe_w[30] = channel_status_bit_q ; //was constant 1'b0 enabling copy-bit;
|
||||
|
||||
// Timeslots 31 = Even Parity bit (31:4)
|
||||
assign subframe_w[31] = 1'b0;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Preamble
|
||||
// Preamble and Channel status bit
|
||||
//-----------------------------------------------------------------
|
||||
localparam PREAMBLE_Z = 8'b00010111; // "B" channel A data at start of block
|
||||
localparam PREAMBLE_Y = 8'b00100111; // "W" channel B data
|
||||
localparam PREAMBLE_X = 8'b01000111; // "M" channel A data not at start of block
|
||||
|
||||
reg [7:0] preamble_r;
|
||||
reg channel_status_bit_r;
|
||||
|
||||
always @ *
|
||||
begin
|
||||
@ -172,20 +173,28 @@ begin
|
||||
preamble_r = PREAMBLE_X; // X(M)
|
||||
|
||||
if (subframe_count_q[8:1] == 8'd2) // frame 2 => subframes 4 and 5 => 0 = copy inhibited, 1 = copy permitted
|
||||
channel_status_bit = 1'b1;
|
||||
channel_status_bit_r = 1'b1;
|
||||
else if (subframe_count_q[8:1] == 8'd15) // frame 15 => 0 = no indication, 1 = original media
|
||||
channel_status_bit = 1'b1;
|
||||
channel_status_bit_r = 1'b1;
|
||||
else if (subframe_count_q[8:1] == 8'd25) // frame 24 to 27 => sample frequency, 0100 = 48kHz, 0000 = 44kHz (l2r)
|
||||
channel_status_bit = 1'b1;
|
||||
channel_status_bit_r = 1'b1;
|
||||
else
|
||||
channel_status_bit = 1'b0; // everything else defaults to 0
|
||||
channel_status_bit_r = 1'b0; // everything else defaults to 0
|
||||
end
|
||||
|
||||
always @ (posedge rst_i or posedge clk_i )
|
||||
if (rst_i == 1'b1)
|
||||
begin
|
||||
if (rst_i == 1'b1)
|
||||
begin
|
||||
preamble_q <= 8'h00;
|
||||
else if (load_subframe_q)
|
||||
channel_status_bit_q <= 1'b0;
|
||||
end
|
||||
else if (load_subframe_q)
|
||||
begin
|
||||
preamble_q <= preamble_r;
|
||||
channel_status_bit_q <= channel_status_bit_r;
|
||||
end
|
||||
end
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Parity Counter
|
||||
|
@ -3,12 +3,14 @@ set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) s
|
||||
set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) math.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) gamma_corr.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_freak.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) arcade_video.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ]
|
||||
@ -23,6 +25,7 @@ set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) s
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mt32pi.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mcp23009.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) f2sdram_safe_terminator.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ddr_svc.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sd_card.sv ]
|
||||
|
@ -218,6 +218,7 @@ set_location_assignment PIN_W20 -to SW[3]
|
||||
|
||||
set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALSPIMASTER_X52_Y72_N111 -entity sys_top -to spi
|
||||
set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALUART_X52_Y67_N111 -entity sys_top -to uart
|
||||
set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALI2C_X52_Y60_N111 -entity sys_top -to hdmi_i2c
|
||||
|
||||
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl"
|
||||
|
||||
|
@ -4,6 +4,7 @@ create_clock -period "50.0 MHz" [get_ports FPGA_CLK2_50]
|
||||
create_clock -period "50.0 MHz" [get_ports FPGA_CLK3_50]
|
||||
create_clock -period "100.0 MHz" [get_pins -compatibility_mode *|h2f_user0_clk]
|
||||
create_clock -period "100.0 MHz" [get_pins -compatibility_mode spi|sclk_out] -name spi_sck
|
||||
create_clock -period "10.0 MHz" [get_pins -compatibility_mode hdmi_i2c|out_clk] -name hdmi_sck
|
||||
|
||||
derive_pll_clocks
|
||||
derive_clock_uncertainty
|
||||
@ -14,6 +15,7 @@ set_clock_groups -exclusive \
|
||||
-group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|*[0].*|divclk}] \
|
||||
-group [get_clocks { pll_audio|pll_audio_inst|altera_pll_i|*[0].*|divclk}] \
|
||||
-group [get_clocks { spi_sck}] \
|
||||
-group [get_clocks { hdmi_sck}] \
|
||||
-group [get_clocks { *|h2f_user0_clk}] \
|
||||
-group [get_clocks { FPGA_CLK1_50 }] \
|
||||
-group [get_clocks { FPGA_CLK2_50 }] \
|
||||
@ -30,7 +32,7 @@ set_false_path -to {cfg[*]}
|
||||
set_false_path -from {cfg[*]}
|
||||
set_false_path -from {VSET[*]}
|
||||
set_false_path -to {wcalc[*] hcalc[*]}
|
||||
set_false_path -to {width[*] height[*]}
|
||||
set_false_path -to {hdmi_width[*] hdmi_height[*]}
|
||||
|
||||
set_multicycle_path -to {*_osd|osd_vcnt*} -setup 2
|
||||
set_multicycle_path -to {*_osd|osd_vcnt*} -hold 1
|
||||
@ -60,3 +62,8 @@ set_false_path -from {ascal|o_ivsize*}
|
||||
set_false_path -from {ascal|o_format*}
|
||||
set_false_path -from {ascal|o_hdown}
|
||||
set_false_path -from {ascal|o_vdown}
|
||||
set_false_path -from {ascal|o_hmin* ascal|o_hmax* ascal|o_vmin* ascal|o_vmax*}
|
||||
set_false_path -from {ascal|o_hdisp* ascal|o_vdisp*}
|
||||
set_false_path -from {ascal|o_htotal* ascal|o_vtotal*}
|
||||
set_false_path -from {ascal|o_hsstart* ascal|o_vsstart* ascal|o_hsend* ascal|o_vsend*}
|
||||
set_false_path -from {ascal|o_hsize* ascal|o_vsize*}
|
||||
|
194
sys/sys_top.v
194
sys/sys_top.v
@ -316,7 +316,7 @@ reg [6:0] coef_addr;
|
||||
reg [8:0] coef_data;
|
||||
reg coef_wr = 0;
|
||||
|
||||
wire[11:0] ARX, ARY;
|
||||
wire[12:0] ARX, ARY;
|
||||
reg [11:0] VSET = 0, HSET = 0;
|
||||
reg FREESCALE = 0;
|
||||
reg [2:0] scaler_flt;
|
||||
@ -337,10 +337,10 @@ reg [23:0] acy0 = -24'd6216759;
|
||||
reg [23:0] acy1 = 24'd6143386;
|
||||
reg [23:0] acy2 = -24'd2023767;
|
||||
reg areset = 0;
|
||||
reg [11:0] arc1x = 0;
|
||||
reg [11:0] arc1y = 0;
|
||||
reg [11:0] arc2x = 0;
|
||||
reg [11:0] arc2y = 0;
|
||||
reg [12:0] arc1x = 0;
|
||||
reg [12:0] arc1y = 0;
|
||||
reg [12:0] arc2x = 0;
|
||||
reg [12:0] arc2y = 0;
|
||||
|
||||
always@(posedge clk_sys) begin
|
||||
reg [7:0] cmd;
|
||||
@ -430,6 +430,7 @@ always@(posedge clk_sys) begin
|
||||
6: LFB_HMAX <= io_din[11:0];
|
||||
7: LFB_VMIN <= io_din[11:0];
|
||||
8: LFB_VMAX <= io_din[11:0];
|
||||
9: LFB_STRIDE <= io_din[13:0];
|
||||
endcase
|
||||
end
|
||||
if(cmd == 'h25) {led_overtake, led_state} <= io_din;
|
||||
@ -462,10 +463,10 @@ always@(posedge clk_sys) begin
|
||||
if(cmd == 'h3A) begin
|
||||
cnt <= cnt + 1'd1;
|
||||
case(cnt[3:0])
|
||||
0: arc1x <= io_din[11:0];
|
||||
1: arc1y <= io_din[11:0];
|
||||
2: arc2x <= io_din[11:0];
|
||||
3: arc2y <= io_din[11:0];
|
||||
0: arc1x <= io_din[12:0];
|
||||
1: arc1y <= io_din[12:0];
|
||||
2: arc2x <= io_din[12:0];
|
||||
3: arc2y <= io_din[12:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
@ -747,6 +748,7 @@ reg [11:0] LFB_HMAX = 0;
|
||||
reg [11:0] LFB_VMIN = 0;
|
||||
reg [11:0] LFB_VMAX = 0;
|
||||
reg [31:0] LFB_BASE = 0;
|
||||
reg [13:0] LFB_STRIDE = 0;
|
||||
|
||||
reg FB_EN = 0;
|
||||
reg [5:0] FB_FMT = 0;
|
||||
@ -762,7 +764,7 @@ always @(posedge clk_sys) begin
|
||||
FB_WIDTH <= LFB_WIDTH;
|
||||
FB_HEIGHT <= LFB_HEIGHT;
|
||||
FB_BASE <= LFB_BASE;
|
||||
FB_STRIDE <= 0;
|
||||
FB_STRIDE <= LFB_STRIDE;
|
||||
end
|
||||
else begin
|
||||
FB_FMT <= fb_fmt;
|
||||
@ -778,74 +780,123 @@ reg fb_vbl;
|
||||
always @(posedge clk_vid) fb_vbl <= hdmi_vbl;
|
||||
`endif
|
||||
|
||||
reg ar_md_start;
|
||||
wire ar_md_busy;
|
||||
reg [11:0] ar_md_mul1, ar_md_mul2, ar_md_div;
|
||||
wire [11:0] ar_md_res;
|
||||
|
||||
sys_umuldiv #(12,12,12) ar_muldiv
|
||||
(
|
||||
.clk(clk_vid),
|
||||
.start(ar_md_start),
|
||||
.busy(ar_md_busy),
|
||||
|
||||
.mul1(ar_md_mul1),
|
||||
.mul2(ar_md_mul2),
|
||||
.div(ar_md_div),
|
||||
.result(ar_md_res)
|
||||
);
|
||||
|
||||
reg [11:0] hmin;
|
||||
reg [11:0] hmax;
|
||||
reg [11:0] vmin;
|
||||
reg [11:0] vmax;
|
||||
reg [11:0] hdmi_height;
|
||||
reg [11:0] hdmi_width;
|
||||
|
||||
always @(posedge clk_vid) begin
|
||||
reg [31:0] wcalc;
|
||||
reg [31:0] hcalc;
|
||||
reg [11:0] hmini,hmaxi,vmini,vmaxi;
|
||||
reg [11:0] wcalc,videow,arx;
|
||||
reg [11:0] hcalc,videoh,ary;
|
||||
reg [2:0] state;
|
||||
reg [11:0] videow;
|
||||
reg [11:0] videoh;
|
||||
reg [11:0] height;
|
||||
reg [11:0] width;
|
||||
reg [11:0] arx;
|
||||
reg [11:0] ary;
|
||||
reg xy;
|
||||
|
||||
height <= (VSET && (VSET < HEIGHT)) ? VSET : HEIGHT;
|
||||
width <= (HSET && (HSET < WIDTH)) ? HSET : WIDTH;
|
||||
hdmi_height <= (VSET && (VSET < HEIGHT)) ? VSET : HEIGHT;
|
||||
hdmi_width <= (HSET && (HSET < WIDTH)) ? HSET : WIDTH;
|
||||
|
||||
if(!ARY) begin
|
||||
if(ARX == 1) begin
|
||||
arx <= arc1x;
|
||||
ary <= arc1y;
|
||||
arx <= arc1x[11:0];
|
||||
ary <= arc1y[11:0];
|
||||
xy <= arc1x[12] | arc1y[12];
|
||||
end
|
||||
else if(ARX == 2) begin
|
||||
arx <= arc2x;
|
||||
ary <= arc2y;
|
||||
arx <= arc2x[11:0];
|
||||
ary <= arc2y[11:0];
|
||||
xy <= arc2x[12] | arc2y[12];
|
||||
end
|
||||
else begin
|
||||
arx <= 0;
|
||||
ary <= 0;
|
||||
xy <= 0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
arx <= ARX;
|
||||
ary <= ARY;
|
||||
arx <= ARX[11:0];
|
||||
ary <= ARY[11:0];
|
||||
xy <= ARX[12] | ARY[12];
|
||||
end
|
||||
|
||||
ar_md_start <= 0;
|
||||
state <= state + 1'd1;
|
||||
case(state)
|
||||
0: if(LFB_EN) begin
|
||||
hmin <= LFB_HMIN;
|
||||
vmin <= LFB_VMIN;
|
||||
hmax <= LFB_HMAX;
|
||||
vmax <= LFB_VMAX;
|
||||
state<= 0;
|
||||
hmini <= LFB_HMIN;
|
||||
vmini <= LFB_VMIN;
|
||||
hmaxi <= LFB_HMAX;
|
||||
vmaxi <= LFB_VMAX;
|
||||
state <= 0;
|
||||
end
|
||||
else if(FREESCALE || !arx || !ary) begin
|
||||
wcalc <= width;
|
||||
hcalc <= height;
|
||||
wcalc <= hdmi_width;
|
||||
hcalc <= hdmi_height;
|
||||
state <= 6;
|
||||
end
|
||||
else begin
|
||||
wcalc <= (height*arx)/ary;
|
||||
hcalc <= (width*ary)/arx;
|
||||
else if(xy) begin
|
||||
wcalc <= arx;
|
||||
hcalc <= ary;
|
||||
state <= 6;
|
||||
end
|
||||
|
||||
1: begin
|
||||
ar_md_mul1 <= hdmi_height;
|
||||
ar_md_mul2 <= arx;
|
||||
ar_md_div <= ary;
|
||||
ar_md_start<= 1;
|
||||
end
|
||||
2: begin
|
||||
wcalc <= ar_md_res;
|
||||
if(ar_md_start | ar_md_busy) state <= 2;
|
||||
end
|
||||
|
||||
3: begin
|
||||
ar_md_mul1 <= hdmi_width;
|
||||
ar_md_mul2 <= ary;
|
||||
ar_md_div <= arx;
|
||||
ar_md_start<= 1;
|
||||
end
|
||||
4: begin
|
||||
hcalc <= ar_md_res;
|
||||
if(ar_md_start | ar_md_busy) state <= 4;
|
||||
end
|
||||
|
||||
6: begin
|
||||
videow <= (wcalc > width) ? width : wcalc[11:0];
|
||||
videoh <= (hcalc > height) ? height : hcalc[11:0];
|
||||
videow <= (wcalc > hdmi_width) ? hdmi_width : wcalc[11:0];
|
||||
videoh <= (hcalc > hdmi_height) ? hdmi_height : hcalc[11:0];
|
||||
end
|
||||
|
||||
7: begin
|
||||
hmin <= ((WIDTH - videow)>>1);
|
||||
hmax <= ((WIDTH - videow)>>1) + videow - 1'd1;
|
||||
vmin <= ((HEIGHT - videoh)>>1);
|
||||
vmax <= ((HEIGHT - videoh)>>1) + videoh - 1'd1;
|
||||
hmini <= ((WIDTH - videow)>>1);
|
||||
hmaxi <= ((WIDTH - videow)>>1) + videow - 1'd1;
|
||||
vmini <= ((HEIGHT - videoh)>>1);
|
||||
vmaxi <= ((HEIGHT - videoh)>>1) + videoh - 1'd1;
|
||||
end
|
||||
endcase
|
||||
|
||||
hmin <= hmini;
|
||||
hmax <= hmaxi;
|
||||
vmin <= vmini;
|
||||
vmax <= vmaxi;
|
||||
end
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
@ -1000,6 +1051,18 @@ hdmi_config hdmi_config
|
||||
.ypbpr(ypbpr_en & direct_video)
|
||||
);
|
||||
|
||||
assign HDMI_I2C_SCL = hdmi_scl_en ? 1'b0 : 1'bZ;
|
||||
assign HDMI_I2C_SDA = hdmi_sda_en ? 1'b0 : 1'bZ;
|
||||
|
||||
wire hdmi_scl_en, hdmi_sda_en;
|
||||
cyclonev_hps_interface_peripheral_i2c hdmi_i2c
|
||||
(
|
||||
.out_clk(hdmi_scl_en),
|
||||
.scl(HDMI_I2C_SCL),
|
||||
.out_data(hdmi_sda_en),
|
||||
.sda(HDMI_I2C_SDA)
|
||||
);
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
wire [23:0] hdmi_data_sl;
|
||||
wire hdmi_de_sl, hdmi_vs_sl, hdmi_hs_sl;
|
||||
@ -1210,32 +1273,45 @@ wire vga_cs_osd;
|
||||
csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);
|
||||
|
||||
`ifndef DUAL_SDRAM
|
||||
wire vs1 = (vga_fb | vga_scaler) ? hdmi_vs_osd : vga_vs_osd;
|
||||
wire hs1 = (vga_fb | vga_scaler) ? hdmi_hs_osd : vga_hs_osd;
|
||||
wire cs1 = (vga_fb | vga_scaler) ? hdmi_cs_osd : vga_cs_osd;
|
||||
wire [23:0] vgas_o;
|
||||
wire vgas_hs, vgas_vs, vgas_cs;
|
||||
vga_out vga_scaler_out
|
||||
(
|
||||
.clk(clk_hdmi),
|
||||
.ypbpr_en(ypbpr_en),
|
||||
.hsync(hdmi_hs_osd),
|
||||
.vsync(hdmi_vs_osd),
|
||||
.csync(hdmi_cs_osd),
|
||||
.dout(vgas_o),
|
||||
.din({24{hdmi_de_osd}} & hdmi_data_osd),
|
||||
.hsync_o(vgas_hs),
|
||||
.vsync_o(vgas_vs),
|
||||
.csync_o(vgas_cs)
|
||||
);
|
||||
|
||||
wire [23:0] vga_o;
|
||||
wire vga_hs, vga_vs, vga_cs;
|
||||
vga_out vga_out
|
||||
(
|
||||
.clk(clk_vid),
|
||||
.ypbpr_full(0),
|
||||
.ypbpr_en(ypbpr_en),
|
||||
.hsync(hs1),
|
||||
.vsync(vs1),
|
||||
.csync(cs1),
|
||||
.hsync(vga_hs_osd),
|
||||
.vsync(vga_vs_osd),
|
||||
.csync(vga_cs_osd),
|
||||
.dout(vga_o),
|
||||
.din((vga_fb | vga_scaler) ? {24{hdmi_de_osd}} & hdmi_data_osd : vga_data_osd),
|
||||
.din(vga_data_osd),
|
||||
.hsync_o(vga_hs),
|
||||
.vsync_o(vga_vs),
|
||||
.csync_o(vga_cs)
|
||||
);
|
||||
|
||||
assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : csync_en ? 1'b1 : ~vga_vs;
|
||||
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : csync_en ? ~vga_cs : ~vga_hs;
|
||||
assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[23:18];
|
||||
assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[15:10];
|
||||
assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[7:2];
|
||||
wire cs1 = (vga_fb | vga_scaler) ? vgas_cs : vga_cs;
|
||||
|
||||
assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : ((vga_fb | vga_scaler) ? ~vgas_vs : ~vga_vs) | csync_en;
|
||||
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : (vga_fb | vga_scaler) ? (csync_en ? ~vgas_cs : ~vgas_hs) : (csync_en ? ~vga_cs : ~vga_hs);
|
||||
assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[23:18] : vga_o[23:18];
|
||||
assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[15:10] : vga_o[15:10];
|
||||
assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[7:2] : vga_o[7:2] ;
|
||||
`endif
|
||||
|
||||
reg video_sync = 0;
|
||||
@ -1458,7 +1534,10 @@ emu emu
|
||||
(
|
||||
.CLK_50M(FPGA_CLK2_50),
|
||||
.RESET(reset),
|
||||
.HPS_BUS({f1, HDMI_TX_VS, clk_100m, clk_ihdmi, ce_hpix, hde_emu, hhs_fix, hvs_fix, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}),
|
||||
.HPS_BUS({f1, HDMI_TX_VS,
|
||||
clk_100m, clk_ihdmi,
|
||||
ce_hpix, hde_emu, hhs_fix, hvs_fix,
|
||||
io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}),
|
||||
|
||||
.VGA_R(r_out),
|
||||
.VGA_G(g_out),
|
||||
@ -1469,6 +1548,9 @@ emu emu
|
||||
.VGA_F1(f1),
|
||||
.VGA_SCALER(vga_force_scaler),
|
||||
|
||||
.HDMI_WIDTH(direct_video ? 12'd0 : hdmi_width),
|
||||
.HDMI_HEIGHT(direct_video ? 12'd0 : hdmi_height),
|
||||
|
||||
.CLK_VIDEO(clk_vid),
|
||||
.CE_PIXEL(ce_pix),
|
||||
.VGA_SL(scanlines),
|
||||
|
195
sys/sysmem.sv
195
sys/sysmem.sv
@ -44,41 +44,182 @@ module sysmem_lite
|
||||
|
||||
assign reset_out = ~init_reset_n | ~hps_h2f_reset_n | reset_core_req;
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//// f2sdram_safe_terminator_ram1 ////
|
||||
////////////////////////////////////////////////////////
|
||||
wire [28:0] f2h_ram1_address;
|
||||
wire [7:0] f2h_ram1_burstcount;
|
||||
wire f2h_ram1_waitrequest;
|
||||
wire [63:0] f2h_ram1_readdata;
|
||||
wire f2h_ram1_readdatavalid;
|
||||
wire f2h_ram1_read;
|
||||
wire [63:0] f2h_ram1_writedata;
|
||||
wire [7:0] f2h_ram1_byteenable;
|
||||
wire f2h_ram1_write;
|
||||
|
||||
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS"} *) reg ram1_reset_0 = 1'b1;
|
||||
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS"} *) reg ram1_reset_1 = 1'b1;
|
||||
always @(posedge ram1_clk) begin
|
||||
ram1_reset_0 <= reset_out;
|
||||
ram1_reset_1 <= ram1_reset_0;
|
||||
end
|
||||
|
||||
f2sdram_safe_terminator #(64, 8) f2sdram_safe_terminator_ram1
|
||||
(
|
||||
.clk (ram1_clk),
|
||||
.rst_req_sync (ram1_reset_1),
|
||||
|
||||
.waitrequest_slave (ram1_waitrequest),
|
||||
.burstcount_slave (ram1_burstcount),
|
||||
.address_slave (ram1_address),
|
||||
.readdata_slave (ram1_readdata),
|
||||
.readdatavalid_slave (ram1_readdatavalid),
|
||||
.read_slave (ram1_read),
|
||||
.writedata_slave (ram1_writedata),
|
||||
.byteenable_slave (ram1_byteenable),
|
||||
.write_slave (ram1_write),
|
||||
|
||||
.waitrequest_master (f2h_ram1_waitrequest),
|
||||
.burstcount_master (f2h_ram1_burstcount),
|
||||
.address_master (f2h_ram1_address),
|
||||
.readdata_master (f2h_ram1_readdata),
|
||||
.readdatavalid_master (f2h_ram1_readdatavalid),
|
||||
.read_master (f2h_ram1_read),
|
||||
.writedata_master (f2h_ram1_writedata),
|
||||
.byteenable_master (f2h_ram1_byteenable),
|
||||
.write_master (f2h_ram1_write)
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//// f2sdram_safe_terminator_ram2 ////
|
||||
////////////////////////////////////////////////////////
|
||||
wire [28:0] f2h_ram2_address;
|
||||
wire [7:0] f2h_ram2_burstcount;
|
||||
wire f2h_ram2_waitrequest;
|
||||
wire [63:0] f2h_ram2_readdata;
|
||||
wire f2h_ram2_readdatavalid;
|
||||
wire f2h_ram2_read;
|
||||
wire [63:0] f2h_ram2_writedata;
|
||||
wire [7:0] f2h_ram2_byteenable;
|
||||
wire f2h_ram2_write;
|
||||
|
||||
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS"} *) reg ram2_reset_0 = 1'b1;
|
||||
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS"} *) reg ram2_reset_1 = 1'b1;
|
||||
always @(posedge ram2_clk) begin
|
||||
ram2_reset_0 <= reset_out;
|
||||
ram2_reset_1 <= ram2_reset_0;
|
||||
end
|
||||
|
||||
f2sdram_safe_terminator #(64, 8) f2sdram_safe_terminator_ram2
|
||||
(
|
||||
.clk (ram2_clk),
|
||||
.rst_req_sync (ram2_reset_1),
|
||||
|
||||
.waitrequest_slave (ram2_waitrequest),
|
||||
.burstcount_slave (ram2_burstcount),
|
||||
.address_slave (ram2_address),
|
||||
.readdata_slave (ram2_readdata),
|
||||
.readdatavalid_slave (ram2_readdatavalid),
|
||||
.read_slave (ram2_read),
|
||||
.writedata_slave (ram2_writedata),
|
||||
.byteenable_slave (ram2_byteenable),
|
||||
.write_slave (ram2_write),
|
||||
|
||||
.waitrequest_master (f2h_ram2_waitrequest),
|
||||
.burstcount_master (f2h_ram2_burstcount),
|
||||
.address_master (f2h_ram2_address),
|
||||
.readdata_master (f2h_ram2_readdata),
|
||||
.readdatavalid_master (f2h_ram2_readdatavalid),
|
||||
.read_master (f2h_ram2_read),
|
||||
.writedata_master (f2h_ram2_writedata),
|
||||
.byteenable_master (f2h_ram2_byteenable),
|
||||
.write_master (f2h_ram2_write)
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//// f2sdram_safe_terminator_vbuf ////
|
||||
////////////////////////////////////////////////////////
|
||||
wire [27:0] f2h_vbuf_address;
|
||||
wire [7:0] f2h_vbuf_burstcount;
|
||||
wire f2h_vbuf_waitrequest;
|
||||
wire [127:0] f2h_vbuf_readdata;
|
||||
wire f2h_vbuf_readdatavalid;
|
||||
wire f2h_vbuf_read;
|
||||
wire [127:0] f2h_vbuf_writedata;
|
||||
wire [15:0] f2h_vbuf_byteenable;
|
||||
wire f2h_vbuf_write;
|
||||
|
||||
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS"} *) reg vbuf_reset_0 = 1'b1;
|
||||
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS"} *) reg vbuf_reset_1 = 1'b1;
|
||||
always @(posedge vbuf_clk) begin
|
||||
vbuf_reset_0 <= reset_out;
|
||||
vbuf_reset_1 <= vbuf_reset_0;
|
||||
end
|
||||
|
||||
f2sdram_safe_terminator #(128, 8) f2sdram_safe_terminator_vbuf
|
||||
(
|
||||
.clk (vbuf_clk),
|
||||
.rst_req_sync (vbuf_reset_1),
|
||||
|
||||
.waitrequest_slave (vbuf_waitrequest),
|
||||
.burstcount_slave (vbuf_burstcount),
|
||||
.address_slave (vbuf_address),
|
||||
.readdata_slave (vbuf_readdata),
|
||||
.readdatavalid_slave (vbuf_readdatavalid),
|
||||
.read_slave (vbuf_read),
|
||||
.writedata_slave (vbuf_writedata),
|
||||
.byteenable_slave (vbuf_byteenable),
|
||||
.write_slave (vbuf_write),
|
||||
|
||||
.waitrequest_master (f2h_vbuf_waitrequest),
|
||||
.burstcount_master (f2h_vbuf_burstcount),
|
||||
.address_master (f2h_vbuf_address),
|
||||
.readdata_master (f2h_vbuf_readdata),
|
||||
.readdatavalid_master (f2h_vbuf_readdatavalid),
|
||||
.read_master (f2h_vbuf_read),
|
||||
.writedata_master (f2h_vbuf_writedata),
|
||||
.byteenable_master (f2h_vbuf_byteenable),
|
||||
.write_master (f2h_vbuf_write)
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//// HPS <> FPGA interfaces ////
|
||||
////////////////////////////////////////////////////////
|
||||
sysmem_HPS_fpga_interfaces fpga_interfaces (
|
||||
.f2h_cold_rst_req_n (~reset_hps_cold_req),
|
||||
.f2h_warm_rst_req_n (~reset_hps_warm_req),
|
||||
.h2f_user0_clk (clock),
|
||||
.h2f_rst_n (hps_h2f_reset_n),
|
||||
.f2h_sdram0_clk (vbuf_clk),
|
||||
.f2h_sdram0_ADDRESS (vbuf_address),
|
||||
.f2h_sdram0_BURSTCOUNT (vbuf_burstcount),
|
||||
.f2h_sdram0_WAITREQUEST (vbuf_waitrequest),
|
||||
.f2h_sdram0_READDATA (vbuf_readdata),
|
||||
.f2h_sdram0_READDATAVALID (vbuf_readdatavalid),
|
||||
.f2h_sdram0_READ (vbuf_read),
|
||||
.f2h_sdram0_WRITEDATA (vbuf_writedata),
|
||||
.f2h_sdram0_BYTEENABLE (vbuf_byteenable),
|
||||
.f2h_sdram0_WRITE (vbuf_write),
|
||||
.f2h_sdram0_ADDRESS (f2h_vbuf_address),
|
||||
.f2h_sdram0_BURSTCOUNT (f2h_vbuf_burstcount),
|
||||
.f2h_sdram0_WAITREQUEST (f2h_vbuf_waitrequest),
|
||||
.f2h_sdram0_READDATA (f2h_vbuf_readdata),
|
||||
.f2h_sdram0_READDATAVALID (f2h_vbuf_readdatavalid),
|
||||
.f2h_sdram0_READ (f2h_vbuf_read),
|
||||
.f2h_sdram0_WRITEDATA (f2h_vbuf_writedata),
|
||||
.f2h_sdram0_BYTEENABLE (f2h_vbuf_byteenable),
|
||||
.f2h_sdram0_WRITE (f2h_vbuf_write),
|
||||
.f2h_sdram1_clk (ram1_clk),
|
||||
.f2h_sdram1_ADDRESS (ram1_address),
|
||||
.f2h_sdram1_BURSTCOUNT (ram1_burstcount),
|
||||
.f2h_sdram1_WAITREQUEST (ram1_waitrequest),
|
||||
.f2h_sdram1_READDATA (ram1_readdata),
|
||||
.f2h_sdram1_READDATAVALID (ram1_readdatavalid),
|
||||
.f2h_sdram1_READ (ram1_read),
|
||||
.f2h_sdram1_WRITEDATA (ram1_writedata),
|
||||
.f2h_sdram1_BYTEENABLE (ram1_byteenable),
|
||||
.f2h_sdram1_WRITE (ram1_write),
|
||||
.f2h_sdram1_ADDRESS (f2h_ram1_address),
|
||||
.f2h_sdram1_BURSTCOUNT (f2h_ram1_burstcount),
|
||||
.f2h_sdram1_WAITREQUEST (f2h_ram1_waitrequest),
|
||||
.f2h_sdram1_READDATA (f2h_ram1_readdata),
|
||||
.f2h_sdram1_READDATAVALID (f2h_ram1_readdatavalid),
|
||||
.f2h_sdram1_READ (f2h_ram1_read),
|
||||
.f2h_sdram1_WRITEDATA (f2h_ram1_writedata),
|
||||
.f2h_sdram1_BYTEENABLE (f2h_ram1_byteenable),
|
||||
.f2h_sdram1_WRITE (f2h_ram1_write),
|
||||
.f2h_sdram2_clk (ram2_clk),
|
||||
.f2h_sdram2_ADDRESS (ram2_address),
|
||||
.f2h_sdram2_BURSTCOUNT (ram2_burstcount),
|
||||
.f2h_sdram2_WAITREQUEST (ram2_waitrequest),
|
||||
.f2h_sdram2_READDATA (ram2_readdata),
|
||||
.f2h_sdram2_READDATAVALID (ram2_readdatavalid),
|
||||
.f2h_sdram2_READ (ram2_read),
|
||||
.f2h_sdram2_WRITEDATA (ram2_writedata),
|
||||
.f2h_sdram2_BYTEENABLE (ram2_byteenable),
|
||||
.f2h_sdram2_WRITE (ram2_write)
|
||||
.f2h_sdram2_ADDRESS (f2h_ram2_address),
|
||||
.f2h_sdram2_BURSTCOUNT (f2h_ram2_burstcount),
|
||||
.f2h_sdram2_WAITREQUEST (f2h_ram2_waitrequest),
|
||||
.f2h_sdram2_READDATA (f2h_ram2_readdata),
|
||||
.f2h_sdram2_READDATAVALID (f2h_ram2_readdatavalid),
|
||||
.f2h_sdram2_READ (f2h_ram2_read),
|
||||
.f2h_sdram2_WRITEDATA (f2h_ram2_writedata),
|
||||
.f2h_sdram2_BYTEENABLE (f2h_ram2_byteenable),
|
||||
.f2h_sdram2_WRITE (f2h_ram2_write)
|
||||
);
|
||||
|
||||
wire hps_h2f_reset_n;
|
||||
|
@ -2,7 +2,6 @@
|
||||
module vga_out
|
||||
(
|
||||
input clk,
|
||||
input ypbpr_full,
|
||||
input ypbpr_en,
|
||||
|
||||
input hsync,
|
||||
@ -17,38 +16,6 @@ module vga_out
|
||||
output reg csync_o
|
||||
);
|
||||
|
||||
wire [5:0] yuv_full[225] = '{
|
||||
6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
|
||||
6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
|
||||
6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
|
||||
6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
|
||||
6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
|
||||
6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
|
||||
6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
|
||||
6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
|
||||
6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
|
||||
6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
|
||||
6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
|
||||
6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
|
||||
6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
|
||||
6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
|
||||
6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
|
||||
6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
|
||||
6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
|
||||
6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
|
||||
6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
|
||||
6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
|
||||
6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
|
||||
6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
|
||||
6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
|
||||
6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
|
||||
6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
|
||||
6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
|
||||
6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
|
||||
6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
|
||||
6'd63
|
||||
};
|
||||
|
||||
wire [5:0] red = din[23:18];
|
||||
wire [5:0] green = din[15:10];
|
||||
wire [5:0] blue = din[7:2];
|
||||
@ -59,12 +26,7 @@ wire [5:0] blue = din[7:2];
|
||||
// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B)
|
||||
|
||||
reg [18:0] y_2, pb_2, pr_2;
|
||||
|
||||
wire [7:0] y = ( y_2[17:8] < 16) ? 8'd16 : ( y_2[17:8] > 235) ? 8'd235 : y_2[15:8];
|
||||
wire [7:0] pb = (pb_2[17:8] < 16) ? 8'd16 : (pb_2[17:8] > 240) ? 8'd240 : pb_2[15:8];
|
||||
wire [7:0] pr = (pr_2[17:8] < 16) ? 8'd16 : (pr_2[17:8] > 240) ? 8'd240 : pr_2[15:8];
|
||||
|
||||
reg [7:0] y_3, pb_3, pr_3;
|
||||
reg [7:0] y, pb, pr;
|
||||
reg [23:0] din2, din3;
|
||||
reg hsync2, vsync2, csync2;
|
||||
always @(posedge clk) begin
|
||||
@ -72,9 +34,9 @@ always @(posedge clk) begin
|
||||
pb_2 <= 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
|
||||
pr_2 <= 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
|
||||
|
||||
y_3 <= {(ypbpr_full ? yuv_full[y -8'd16] : y[7:2]), 2'b00};
|
||||
pb_3 <= {(ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]), 2'b00};
|
||||
pr_3 <= {(ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]), 2'b00};
|
||||
y <= ( y_2[18] || !y_2[17:12]) ? 8'd16 : (y_2[17:8] > 235) ? 8'd235 : y_2[15:8];
|
||||
pb <= (pb_2[18] || !pb_2[17:12]) ? 8'd16 : (&pb_2[17:12]) ? 8'd240 : pb_2[15:8];
|
||||
pr <= (pr_2[18] || !pr_2[17:12]) ? 8'd16 : (&pr_2[17:12]) ? 8'd240 : pr_2[15:8];
|
||||
|
||||
hsync_o <= hsync2; hsync2 <= hsync;
|
||||
vsync_o <= vsync2; vsync2 <= vsync;
|
||||
@ -84,6 +46,6 @@ always @(posedge clk) begin
|
||||
din3 <= din2;
|
||||
end
|
||||
|
||||
assign dout = ypbpr_en ? {pr_3, y_3, pb_3} : din3;
|
||||
assign dout = ypbpr_en ? {pr, y, pb} : din3;
|
||||
|
||||
endmodule
|
||||
|
270
sys/video_freak.sv
Normal file
270
sys/video_freak.sv
Normal file
@ -0,0 +1,270 @@
|
||||
//
|
||||
//
|
||||
// Video crop
|
||||
// Copyright (c) 2020 Grabulosaure, (c) 2021 Alexey Melnikov
|
||||
//
|
||||
// Integer scaling
|
||||
// Copyright (c) 2021 Alexey Melnikov
|
||||
//
|
||||
// This program is GPL Licensed. See COPYING for the full license.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module video_freak
|
||||
(
|
||||
input CLK_VIDEO,
|
||||
input CE_PIXEL,
|
||||
input VGA_VS,
|
||||
input [11:0] HDMI_WIDTH,
|
||||
input [11:0] HDMI_HEIGHT,
|
||||
output VGA_DE,
|
||||
output reg [12:0] VIDEO_ARX,
|
||||
output reg [12:0] VIDEO_ARY,
|
||||
|
||||
input VGA_DE_IN,
|
||||
input [11:0] ARX,
|
||||
input [11:0] ARY,
|
||||
input [11:0] CROP_SIZE,
|
||||
input [4:0] CROP_OFF, // -16...+15
|
||||
input [2:0] SCALE //0 - normal, 1 - V-integer, 2 - HV-Integer-, 3 - HV-Integer+, 4 - HV-Integer
|
||||
);
|
||||
|
||||
reg mul_start;
|
||||
wire mul_run;
|
||||
reg [11:0] mul_arg1, mul_arg2;
|
||||
wire [23:0] mul_res;
|
||||
sys_umul #(12,12) mul(CLK_VIDEO,mul_start,mul_run, mul_arg1,mul_arg2,mul_res);
|
||||
|
||||
reg vde;
|
||||
reg [11:0] arxo,aryo;
|
||||
reg [11:0] vsize;
|
||||
reg [11:0] hsize;
|
||||
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg old_de, old_vs,ovde;
|
||||
reg [11:0] vtot,vcpt,vcrop,voff;
|
||||
reg [11:0] hcpt;
|
||||
reg [11:0] vadj;
|
||||
reg [23:0] ARXG,ARYG;
|
||||
reg [11:0] arx,ary;
|
||||
reg [1:0] vcalc;
|
||||
|
||||
if (CE_PIXEL) begin
|
||||
old_de <= VGA_DE_IN;
|
||||
old_vs <= VGA_VS;
|
||||
if (VGA_VS & ~old_vs) begin
|
||||
vcpt <= 0;
|
||||
vtot <= vcpt;
|
||||
vcalc <= 1;
|
||||
vcrop <= (CROP_SIZE >= vcpt) ? 12'd0 : CROP_SIZE;
|
||||
end
|
||||
|
||||
if (VGA_DE_IN) hcpt <= hcpt + 1'd1;
|
||||
if (~VGA_DE_IN & old_de) begin
|
||||
vcpt <= vcpt + 1'd1;
|
||||
if(!vcpt) hsize <= hcpt;
|
||||
hcpt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
arx <= ARX;
|
||||
ary <= ARY;
|
||||
|
||||
vsize <= vcrop;
|
||||
|
||||
mul_start <= 0;
|
||||
|
||||
if(!vcrop || !ary || !arx) begin
|
||||
arxo <= arx;
|
||||
aryo <= ary;
|
||||
vsize <= vtot;
|
||||
end
|
||||
else if (vcalc) begin
|
||||
if(~mul_start & ~mul_run) begin
|
||||
vcalc <= vcalc + 1'd1;
|
||||
case(vcalc)
|
||||
1: begin
|
||||
mul_arg1 <= arx;
|
||||
mul_arg2 <= vtot;
|
||||
mul_start <= 1;
|
||||
end
|
||||
|
||||
2: begin
|
||||
ARXG <= mul_res;
|
||||
mul_arg1 <= ary;
|
||||
mul_arg2 <= vcrop;
|
||||
mul_start <= 1;
|
||||
end
|
||||
|
||||
3: begin
|
||||
ARYG <= mul_res;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
else if (ARXG[23] | ARYG[23]) begin
|
||||
arxo <= ARXG[23:12];
|
||||
aryo <= ARYG[23:12];
|
||||
end
|
||||
else begin
|
||||
ARXG <= ARXG << 1;
|
||||
ARYG <= ARYG << 1;
|
||||
end
|
||||
|
||||
vadj <= (vtot-vcrop) + {{6{CROP_OFF[4]}},CROP_OFF,1'b0};
|
||||
voff <= vadj[11] ? 12'd0 : ((vadj[11:1] + vcrop) > vtot) ? vtot-vcrop : vadj[11:1];
|
||||
ovde <= ((vcpt >= voff) && (vcpt < (vcrop + voff))) || !vcrop;
|
||||
vde <= ovde;
|
||||
end
|
||||
|
||||
assign VGA_DE = vde & VGA_DE_IN;
|
||||
|
||||
video_scale_int scale
|
||||
(
|
||||
.CLK_VIDEO(CLK_VIDEO),
|
||||
.HDMI_WIDTH(HDMI_WIDTH),
|
||||
.HDMI_HEIGHT(HDMI_HEIGHT),
|
||||
.SCALE(SCALE),
|
||||
.hsize(hsize),
|
||||
.vsize(vsize),
|
||||
.arx_i(arxo),
|
||||
.ary_i(aryo),
|
||||
.arx_o(VIDEO_ARX),
|
||||
.ary_o(VIDEO_ARY)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module video_scale_int
|
||||
(
|
||||
input CLK_VIDEO,
|
||||
|
||||
input [11:0] HDMI_WIDTH,
|
||||
input [11:0] HDMI_HEIGHT,
|
||||
|
||||
input [2:0] SCALE,
|
||||
|
||||
input [11:0] hsize,
|
||||
input [11:0] vsize,
|
||||
|
||||
input [11:0] arx_i,
|
||||
input [11:0] ary_i,
|
||||
|
||||
output reg [12:0] arx_o,
|
||||
output reg [12:0] ary_o
|
||||
);
|
||||
|
||||
reg div_start;
|
||||
wire div_run;
|
||||
reg [23:0] div_num;
|
||||
reg [11:0] div_den;
|
||||
wire [23:0] div_res;
|
||||
sys_udiv #(24,12) div(CLK_VIDEO,div_start,div_run, div_num,div_den,div_res);
|
||||
|
||||
reg mul_start;
|
||||
wire mul_run;
|
||||
reg [11:0] mul_arg1, mul_arg2;
|
||||
wire [23:0] mul_res;
|
||||
sys_umul #(12,12) mul(CLK_VIDEO,mul_start,mul_run, mul_arg1,mul_arg2,mul_res);
|
||||
|
||||
wire [11:0] wideres = mul_res[11:0] + hsize;
|
||||
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg [11:0] oheight,wres;
|
||||
reg [12:0] arxf,aryf;
|
||||
reg [3:0] cnt;
|
||||
reg narrow;
|
||||
|
||||
div_start <= 0;
|
||||
mul_start <= 0;
|
||||
|
||||
if (!SCALE || !ary_i || !arx_i) begin
|
||||
arxf <= arx_i;
|
||||
aryf <= ary_i;
|
||||
end
|
||||
else if(~div_start & ~div_run & ~mul_start & ~mul_run) begin
|
||||
cnt <= cnt + 1'd1;
|
||||
case(cnt)
|
||||
0: begin
|
||||
div_num <= HDMI_HEIGHT;
|
||||
div_den <= vsize;
|
||||
div_start <= 1;
|
||||
end
|
||||
|
||||
1: if(!div_res[11:0]) begin
|
||||
// screen resolution is lower than video resolution.
|
||||
// Integer scaling is impossible.
|
||||
arxf <= arx_i;
|
||||
aryf <= ary_i;
|
||||
cnt <= 0;
|
||||
end
|
||||
else begin
|
||||
mul_arg1 <= vsize;
|
||||
mul_arg2 <= div_res[11:0];
|
||||
mul_start <= 1;
|
||||
end
|
||||
|
||||
2: begin
|
||||
oheight <= mul_res[11:0];
|
||||
mul_arg1 <= mul_res[11:0];
|
||||
mul_arg2 <= arx_i;
|
||||
mul_start <= 1;
|
||||
end
|
||||
|
||||
3: begin
|
||||
div_num <= mul_res;
|
||||
div_den <= ary_i;
|
||||
div_start <= 1;
|
||||
end
|
||||
|
||||
4: begin
|
||||
div_num <= div_res;
|
||||
div_den <= hsize;
|
||||
div_start <= 1;
|
||||
end
|
||||
|
||||
5: begin
|
||||
mul_arg1 <= hsize;
|
||||
mul_arg2 <= div_res[11:0] ? div_res[11:0] : 12'd1;
|
||||
mul_start <= 1;
|
||||
end
|
||||
|
||||
6: if(mul_res <= HDMI_WIDTH) cnt <= 8;
|
||||
else begin
|
||||
div_num <= HDMI_WIDTH;
|
||||
div_den <= hsize;
|
||||
div_start <= 1;
|
||||
end
|
||||
|
||||
7: begin
|
||||
mul_arg1 <= hsize;
|
||||
mul_arg2 <= div_res[11:0] ? div_res[11:0] : 12'd1;
|
||||
mul_start <= 1;
|
||||
end
|
||||
|
||||
8: begin
|
||||
narrow <= ((div_num[11:0] - mul_res[11:0]) <= (wideres - div_num[11:0])) || (wideres > HDMI_WIDTH);
|
||||
wres <= wideres;
|
||||
end
|
||||
|
||||
9: begin
|
||||
case(SCALE)
|
||||
2: arxf <= {1'b1, mul_res[11:0]};
|
||||
3: arxf <= {1'b1, (wres > HDMI_WIDTH) ? mul_res[11:0] : wres};
|
||||
4: arxf <= {1'b1, narrow ? mul_res[11:0] : wres};
|
||||
default: arxf <= {1'b1, div_num[11:0]};
|
||||
endcase
|
||||
aryf <= {1'b1, oheight};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
arx_o <= arxf;
|
||||
ary_o <= aryf;
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2017 Sorgelig
|
||||
// Copyright (c) 2017,2021 Alexey Melnikov
|
||||
//
|
||||
// This program is GPL Licensed. See COPYING for the full license.
|
||||
//
|
||||
@ -15,8 +15,6 @@
|
||||
// May be less if line_start is used.
|
||||
//
|
||||
// HALF_DEPTH: If =1 then color dept is 4 bits per component
|
||||
// For half depth 8 bits monochrome is available with
|
||||
// mono signal enabled and color = {G, R}
|
||||
//
|
||||
// altera message_off 10720
|
||||
// altera message_off 12161
|
||||
@ -28,32 +26,21 @@ module video_mixer
|
||||
parameter GAMMA = 0
|
||||
)
|
||||
(
|
||||
// video clock
|
||||
// it should be multiple by (ce_pix*4).
|
||||
input clk_vid,
|
||||
input CLK_VIDEO, // should be multiple by (ce_pix*4)
|
||||
output reg CE_PIXEL, // output pixel clock enable
|
||||
|
||||
// Pixel clock or clock_enable (both are accepted).
|
||||
input ce_pix,
|
||||
output ce_pix_out,
|
||||
input ce_pix, // input pixel clock or clock_enable
|
||||
|
||||
input scandoubler,
|
||||
input hq2x, // high quality 2x scaling
|
||||
|
||||
// scanlines (00-none 01-25% 10-50% 11-75%)
|
||||
input [1:0] scanlines,
|
||||
|
||||
// High quality 2x scaling
|
||||
input hq2x,
|
||||
inout [21:0] gamma_bus,
|
||||
|
||||
// color
|
||||
input [DWIDTH:0] R,
|
||||
input [DWIDTH:0] G,
|
||||
input [DWIDTH:0] B,
|
||||
|
||||
// Monochrome mode (for HALF_DEPTH only)
|
||||
input mono,
|
||||
|
||||
inout [21:0] gamma_bus,
|
||||
|
||||
// Positive pulses.
|
||||
input HSync,
|
||||
input VSync,
|
||||
@ -75,9 +62,9 @@ localparam HALF_DEPTH_SD = GAMMA ? 0 : HALF_DEPTH;
|
||||
|
||||
generate
|
||||
if(GAMMA && HALF_DEPTH) begin
|
||||
wire [7:0] R_in = mono ? {G,R} : {R,R};
|
||||
wire [7:0] G_in = mono ? {G,R} : {G,G};
|
||||
wire [7:0] B_in = mono ? {G,R} : {B,B};
|
||||
wire [7:0] R_in = {R,R};
|
||||
wire [7:0] G_in = {G,G};
|
||||
wire [7:0] B_in = {B,B};
|
||||
end else begin
|
||||
wire [DWIDTH:0] R_in = R;
|
||||
wire [DWIDTH:0] G_in = G;
|
||||
@ -95,7 +82,7 @@ generate
|
||||
assign gamma_bus[21] = 1;
|
||||
gamma_corr gamma(
|
||||
.clk_sys(gamma_bus[20]),
|
||||
.clk_vid(clk_vid),
|
||||
.clk_vid(CLK_VIDEO),
|
||||
.ce_pix(ce_pix),
|
||||
|
||||
.gamma_en(gamma_bus[19]),
|
||||
@ -122,7 +109,6 @@ generate
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
wire [DWIDTH_SD:0] R_sd;
|
||||
wire [DWIDTH_SD:0] G_sd;
|
||||
wire [DWIDTH_SD:0] B_sd;
|
||||
@ -130,7 +116,10 @@ wire hs_sd, vs_sd, hb_sd, vb_sd, ce_pix_sd;
|
||||
|
||||
scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH_SD)) sd
|
||||
(
|
||||
.*,
|
||||
.clk_vid(CLK_VIDEO),
|
||||
.hq2x(hq2x),
|
||||
|
||||
.ce_pix(ce_pix),
|
||||
.hs_in(hs_g),
|
||||
.vs_in(vs_g),
|
||||
.hb_in(hb_g),
|
||||
@ -153,86 +142,51 @@ wire [DWIDTH_SD:0] rt = (scandoubler ? R_sd : R_gamma);
|
||||
wire [DWIDTH_SD:0] gt = (scandoubler ? G_sd : G_gamma);
|
||||
wire [DWIDTH_SD:0] bt = (scandoubler ? B_sd : B_gamma);
|
||||
|
||||
generate
|
||||
if(!GAMMA && HALF_DEPTH) begin
|
||||
wire [7:0] r = mono ? {gt,rt} : {rt,rt};
|
||||
wire [7:0] g = mono ? {gt,rt} : {gt,gt};
|
||||
wire [7:0] b = mono ? {gt,rt} : {bt,bt};
|
||||
end else begin
|
||||
wire [7:0] r = rt;
|
||||
wire [7:0] g = gt;
|
||||
wire [7:0] b = bt;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
wire hs = (scandoubler ? hs_sd : hs_g);
|
||||
wire vs = (scandoubler ? vs_sd : vs_g);
|
||||
|
||||
assign ce_pix_out = scandoubler ? ce_pix_sd : ce_pix;
|
||||
|
||||
|
||||
reg scanline = 0;
|
||||
always @(posedge clk_vid) begin
|
||||
reg old_hs, old_vs;
|
||||
|
||||
old_hs <= hs;
|
||||
old_vs <= vs;
|
||||
|
||||
if(old_hs && ~hs) scanline <= ~scanline;
|
||||
if(old_vs && ~vs) scanline <= 0;
|
||||
end
|
||||
|
||||
wire hde = scandoubler ? ~hb_sd : ~hb_g;
|
||||
wire vde = scandoubler ? ~vb_sd : ~vb_g;
|
||||
|
||||
reg [7:0] v_r,v_g,v_b;
|
||||
reg v_vs,v_hs,v_de;
|
||||
always @(posedge clk_vid) begin
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg [7:0] r,g,b;
|
||||
reg hde,vde,hs,vs, old_vs;
|
||||
reg old_hde;
|
||||
reg old_ce;
|
||||
reg ce_osc, fs_osc;
|
||||
|
||||
if(ce_pix_out) begin
|
||||
case(scanlines & {scanline, scanline})
|
||||
1: begin // reduce 25% = 1/2 + 1/4
|
||||
v_r <= {1'b0, r[7:1]} + {2'b00, r[7:2]};
|
||||
v_g <= {1'b0, g[7:1]} + {2'b00, g[7:2]};
|
||||
v_b <= {1'b0, b[7:1]} + {2'b00, b[7:2]};
|
||||
old_ce <= ce_pix;
|
||||
ce_osc <= ce_osc | (old_ce ^ ce_pix);
|
||||
|
||||
old_vs <= vs;
|
||||
if(~old_vs & vs) begin
|
||||
fs_osc <= ce_osc;
|
||||
ce_osc <= 0;
|
||||
end
|
||||
|
||||
2: begin // reduce 50% = 1/2
|
||||
v_r <= {1'b0, r[7:1]};
|
||||
v_g <= {1'b0, g[7:1]};
|
||||
v_b <= {1'b0, b[7:1]};
|
||||
CE_PIXEL <= scandoubler ? ce_pix_sd : fs_osc ? (~old_ce & ce_pix) : ce_pix;
|
||||
|
||||
if(!GAMMA && HALF_DEPTH) begin
|
||||
r <= {rt,rt};
|
||||
g <= {gt,gt};
|
||||
b <= {bt,bt};
|
||||
end
|
||||
else begin
|
||||
r <= rt;
|
||||
g <= gt;
|
||||
b <= bt;
|
||||
end
|
||||
|
||||
3: begin // reduce 75% = 1/4
|
||||
v_r <= {2'b00, r[7:2]};
|
||||
v_g <= {2'b00, g[7:2]};
|
||||
v_b <= {2'b00, b[7:2]};
|
||||
end
|
||||
hde <= scandoubler ? ~hb_sd : ~hb_g;
|
||||
vde <= scandoubler ? ~vb_sd : ~vb_g;
|
||||
vs <= scandoubler ? vs_sd : vs_g;
|
||||
hs <= scandoubler ? hs_sd : hs_g;
|
||||
|
||||
default: begin
|
||||
v_r <= r;
|
||||
v_g <= g;
|
||||
v_b <= b;
|
||||
end
|
||||
endcase
|
||||
if(CE_PIXEL) begin
|
||||
VGA_R <= r;
|
||||
VGA_G <= g;
|
||||
VGA_B <= b;
|
||||
|
||||
v_vs <= vs;
|
||||
v_hs <= hs;
|
||||
VGA_VS <= vs;
|
||||
VGA_HS <= hs;
|
||||
|
||||
old_hde <= hde;
|
||||
if(~old_hde && hde) v_de <= vde;
|
||||
if(old_hde && ~hde) v_de <= 0;
|
||||
if(old_hde ^ hde) VGA_DE <= vde & hde;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_vid) if(ce_pix_out) begin
|
||||
VGA_R <= v_r;
|
||||
VGA_G <= v_g;
|
||||
VGA_B <= v_b;
|
||||
VGA_HS <= v_hs;
|
||||
VGA_VS <= v_vs;
|
||||
VGA_DE <= v_de;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user