Update sys.

This commit is contained in:
sorgelig
2021-01-28 00:07:29 +08:00
parent bfe2674924
commit cc1962452b
14 changed files with 1010 additions and 151 deletions

64
menu.sv
View File

@@ -39,8 +39,8 @@ module emu
output CE_PIXEL,
//Video aspect ratio for HDMI. Most retro systems have ratio 4:3.
output [7:0] VIDEO_ARX,
output [7:0] VIDEO_ARY,
output [11:0] VIDEO_ARX,
output [11:0] VIDEO_ARY,
output [7:0] VGA_R,
output [7:0] VGA_G,
@@ -50,6 +50,34 @@ module emu
output VGA_DE, // = ~(VBlank | HBlank)
output VGA_F1,
output [1:0] VGA_SL,
output VGA_SCALER, // Force VGA scaler
`ifdef USE_FB
// Use framebuffer in DDRAM (USE_FB=1 in qsf)
// FB_FORMAT:
// [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp
// [3] : 0=16bits 565 1=16bits 1555
// [4] : 0=RGB 1=BGR (for 16/24/32 modes)
//
// FB_STRIDE either 0 (rounded to 256 bytes) or multiple of pixel size (in bytes)
output FB_EN,
output [4:0] FB_FORMAT,
output [11:0] FB_WIDTH,
output [11:0] FB_HEIGHT,
output [31:0] FB_BASE,
output [13:0] FB_STRIDE,
input FB_VBL,
input FB_LL,
output FB_FORCE_BLANK,
// Palette control for 8bit modes.
// Ignored for other video modes.
output FB_PAL_CLK,
output [7:0] FB_PAL_ADDR,
output [23:0] FB_PAL_DOUT,
input [23:0] FB_PAL_DIN,
output FB_PAL_WR,
`endif
output LED_USER, // 1 - ON, 0 - OFF.
@@ -58,13 +86,13 @@ module emu
// hint: supply 2'b00 to let the system control the LED.
output [1:0] LED_POWER,
output [1:0] LED_DISK,
// I/O board button press simulation (active high)
// b[1]: user button
// b[0]: osd button
output [1:0] BUTTONS,
input CLK_AUDIO, // 24.576 MHz
// I/O board button press simulation (active high)
// b[1]: user button
// b[0]: osd button
output [1:0] BUTTONS,
input CLK_AUDIO, // 24.576 MHz
output [15:0] AUDIO_L,
output [15:0] AUDIO_R,
output AUDIO_S, // 1 - signed audio samples, 0 - unsigned
@@ -80,6 +108,7 @@ module emu
output SD_CS,
input SD_CD,
`ifdef USE_DDRAM
//High latency DDR3 RAM interface
//Use for non-critical time purposes
output DDRAM_CLK,
@@ -92,7 +121,9 @@ module emu
output [63:0] DDRAM_DIN,
output [7:0] DDRAM_BE,
output DDRAM_WE,
`endif
`ifdef USE_SDRAM
//SDRAM interface with lower latency
output SDRAM_CLK,
output SDRAM_CKE,
@@ -105,6 +136,20 @@ module emu
output SDRAM_nCAS,
output SDRAM_nRAS,
output SDRAM_nWE,
`endif
`ifdef DUAL_SDRAM
//Secondary SDRAM
input SDRAM2_EN,
output SDRAM2_CLK,
output [12:0] SDRAM2_A,
output [1:0] SDRAM2_BA,
inout [15:0] SDRAM2_DQ,
output SDRAM2_nCS,
output SDRAM2_nCAS,
output SDRAM2_nRAS,
output SDRAM2_nWE,
`endif
input UART_CTS,
output UART_RTS,
@@ -136,6 +181,7 @@ assign VGA_SL = 0;
assign VGA_F1 = 0;
assign VIDEO_ARX = 0;
assign VIDEO_ARY = 0;
assign VGA_SCALER= 0;
assign AUDIO_S = 0;
assign AUDIO_L = 0;

View File

@@ -204,7 +204,7 @@ assign DDRAM_DIN = {ram_data,ram_data};
assign DDRAM_WE = ram_wr;
assign DDRAM_RD = 0;
assign FB_EN = ~no_rotate;
assign FB_EN = fb_en[2];
assign FB_FORMAT = 5'b00110;
assign FB_BASE = {MEM_BASE,o_fb,23'd0};
assign FB_WIDTH = vsz;
@@ -236,6 +236,11 @@ always @(posedge CLK_VIDEO) begin
end
end
initial begin
fb_en = 0;
end
reg [2:0] fb_en = 0;
reg [11:0] hsz = 320, vsz = 240;
reg [11:0] bwidth;
reg [22:0] bufsize;
@@ -257,6 +262,7 @@ always @(posedge CLK_VIDEO) begin
vsz <= vcnt;
bwidth <= vcnt + 2'd3;
vcnt <= 0;
fb_en <= {fb_en[1:0], ~no_rotate};
end
if(old_vs & ~VGA_VS) bufsize <= hsz * stride;
end

View File

@@ -462,8 +462,8 @@ ARCHITECTURE rtl OF ascal IS
SIGNAL o_fload : natural RANGE 0 TO 3;
SIGNAL o_acpt,o_acpt1,o_acpt2,o_acpt3,o_acpt4 : natural RANGE 0 TO 15; -- Alternance pixels FIFO
SIGNAL o_dshi : natural RANGE 0 TO 3;
SIGNAL o_first,o_last,o_last1,o_last2,o_last3 : std_logic;
SIGNAL o_lastt1,o_lastt2,o_lastt3 : std_logic;
SIGNAL o_first,o_last,o_last1,o_last2 : std_logic;
SIGNAL o_lastt1,o_lastt2,o_lastt3,o_lastt4 : std_logic;
SIGNAL o_alt,o_altx : unsigned(3 DOWNTO 0);
SIGNAL o_hdown,o_vdown : std_logic;
SIGNAL o_primv,o_lastv,o_bibv : unsigned(0 TO 2);
@@ -2029,7 +2029,8 @@ BEGIN
o_acpt1<=o_acpt; o_acpt2<=o_acpt1; o_acpt3<=o_acpt2; o_acpt4<=o_acpt3;
o_ad1<=o_ad; o_ad2<=o_ad1; o_ad3<=o_ad2;
o_sh1<=o_sh; o_sh2<=o_sh1; o_sh3<=o_sh2; o_sh4<=o_sh3;
o_lastt1<=o_last; o_lastt2<=o_lastt1; o_lastt3<=o_lastt2;
o_lastt1<=o_last; o_lastt2<=o_lastt1;
o_lastt3<=o_lastt2; o_lastt4<=o_lastt3;
------------------------------------------------------
IF o_sh3='1' THEN
@@ -2059,7 +2060,7 @@ BEGIN
o_hpix2<=hpix_v;
o_first<='0';
END IF;
IF o_lastt3='1' THEN
IF o_lastt4='1' THEN
-- Right edge. Keep last pixel.
o_hpix0<=o_hpix0;
END IF;

View File

@@ -0,0 +1,300 @@
// ============================================================================
//
// 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
/*
* Safe terminating burst writing
*/
wire on_write_transaction = state_write && next_state_write;
wire on_start_write_transaction = !state_write && next_state_write;
reg write_terminating = 1'b0;
reg write_terminated = 1'b0;
reg [BURSTCOUNT_WIDTH-1:0] write_terminate_burstcount_latch = 0;
reg [ADDRESS_WITDH-1:0] write_terminate_address_latch = 0;
reg [BURSTCOUNT_WIDTH-1:0] write_terminate_counter = 0;
always_ff @(posedge clk) begin
if (rst_req_sync) begin
// Reset assert
if (init_reset_deasserted) begin
if (!lock_stage) begin
if (on_write_transaction) begin
write_terminating <= 1'b1;
write_terminate_burstcount_latch <= write_burstcount_latch;
write_terminate_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_terminated <= 1'b1;
end else begin
write_terminating <= 1'b1;
write_terminate_burstcount_latch <= burstcount_slave;
write_terminate_address_latch <= address_slave;
write_terminate_counter <= waitrequest_master ? 1'd0 : 1'd1;
end
end else begin
write_terminated <= 1'b1;
end
end
end
end else begin
// Reset deassert
if (!write_terminating) begin
write_terminated <= 1'b0;
end
end
if (write_terminating) begin
// Continue write transaction until the end
if (!waitrequest_master) begin
write_terminate_counter <= write_terminate_counter + 1'd1;
end
if (write_terminate_counter == write_terminate_burstcount_latch - 'd1) begin
write_terminating <= 1'b0;
write_terminated <= 1'b1;
end
end
end
/*
* Safe terminating burst reading
*/
reg [BURSTCOUNT_WIDTH-1:0] read_burstcount_latch = 0;
reg [ADDRESS_WITDH-1:0] read_address_latch = 0;
reg read_terminating = 1'b0;
reg read_siganl_in_terminating = 1'b0;
always_ff @(posedge clk) begin
if (rst_req_sync) begin
// Reset assert
if (init_reset_deasserted) begin
if (!lock_stage) begin
if (read_slave && waitrequest_master) begin
// Need to keep read signal, burstcount and address until waitrequest_master deasserted
read_siganl_in_terminating <= 1'b1;
read_burstcount_latch <= burstcount_slave;
read_address_latch <= address_slave;
read_terminating <= 1'b1;
end else if (!on_write_transaction && !on_start_write_transaction) 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 something.
// Assume that reading is in progress when we are not on write transaction.
read_siganl_in_terminating <= 0;
read_burstcount_latch <= 1;
read_address_latch <= 0;
read_siganl_in_terminating <= 0;
read_terminating <= 1;
end
end else begin
if (!waitrequest_master) begin
read_siganl_in_terminating <= 1'b0;
end
end
end
end else begin
// Reset deassert
read_terminating <= 1'b0;
end
end
/*
* Bus mux depending on the stage.
*/
always_comb begin
if (read_terminating) begin
burstcount_master = read_burstcount_latch;
address_master = read_address_latch;
read_master = read_siganl_in_terminating;
writedata_master = 0;
byteenable_master = '1; // all 1
write_master = 0;
end else if (write_terminating) begin
burstcount_master = write_terminate_burstcount_latch;
address_master = write_terminate_address_latch;
read_master = 0;
writedata_master = 0;
byteenable_master = '1; // all 1
write_master = 1;
end else if (write_terminated) begin
burstcount_master = 1;
address_master = 0;
read_master = 0;
writedata_master = 0;
byteenable_master = 0;
write_master = 0;
end else begin
burstcount_master = burstcount_slave;
address_master = address_slave;
read_master = read_slave;
writedata_master = writedata_slave;
byteenable_master = byteenable_slave;
write_master = write_slave;
end
end
// Just passing through master to slave
assign waitrequest_slave = waitrequest_master;
assign readdata_slave = readdata_master;
assign readdatavalid_slave = readdatavalid_master;
endmodule

View File

@@ -111,32 +111,32 @@ wire [15:0] init_data[82] =
{8'h17, 8'b01100010}, // Aspect ratio 16:9 [1]=1, 4:3 [1]=0
{8'h18, ypbpr ? 8'h88 : limited[0] ? 8'h8D : limited[1] ? 8'h8E : 8'h00}, // CSC Scaling Factors and Coefficients for RGB Full->Limited.
{8'h19, ypbpr ? 8'h2E : limited[0] ? 8'hBC : 8'hFE}, // Taken from table in ADV7513 Programming Guide.
{8'h1A, ypbpr ? 8'h18 : 8'h00}, // CSC Channel A.
{8'h1B, ypbpr ? 8'h93 : 8'h00},
{8'h1C, ypbpr ? 8'h1F : 8'h00},
{8'h1D, ypbpr ? 8'h3F : 8'h00},
{8'h1E, ypbpr ? 8'h08 : 8'h01},
{8'h1F, 8'h00},
{8'h18, ypbpr ? 8'h86 : limited[0] ? 8'h8D : limited[1] ? 8'h8E : 8'h00}, // CSC Scaling Factors and Coefficients for RGB Full->Limited.
{8'h19, ypbpr ? 8'hDF : limited[0] ? 8'hBC : 8'hFE}, // Taken from table in ADV7513 Programming Guide.
{8'h1A, ypbpr ? 8'h1A : 8'h00}, // CSC Channel A.
{8'h1B, ypbpr ? 8'h3F : 8'h00},
{8'h1C, ypbpr ? 8'h1E : 8'h00},
{8'h1D, ypbpr ? 8'hE2 : 8'h00},
{8'h1E, ypbpr ? 8'h07 : 8'h01},
{8'h1F, ypbpr ? 8'hE7 : 8'h00},
{8'h20, ypbpr ? 8'h03 : 8'h00}, // CSC Channel B.
{8'h21, ypbpr ? 8'h67 : 8'h00},
{8'h22, ypbpr ? 8'h0B : limited[0] ? 8'h0D : 8'h0E},
{8'h23, ypbpr ? 8'h71 : limited[0] ? 8'hBC : 8'hFE},
{8'h20, ypbpr ? 8'h04 : 8'h00}, // CSC Channel B.
{8'h21, ypbpr ? 8'h1C : 8'h00},
{8'h22, ypbpr ? 8'h08 : limited[0] ? 8'h0D : 8'h0E},
{8'h23, ypbpr ? 8'h11 : limited[0] ? 8'hBC : 8'hFE},
{8'h24, ypbpr ? 8'h01 : 8'h00},
{8'h25, ypbpr ? 8'h28 : 8'h00},
{8'h26, ypbpr ? 8'h00 : 8'h01},
{8'h25, ypbpr ? 8'h91 : 8'h00},
{8'h26, ypbpr ? 8'h01 : 8'h01},
{8'h27, 8'h00},
{8'h28, ypbpr ? 8'h1E : 8'h00}, // CSC Channel C.
{8'h29, ypbpr ? 8'h21 : 8'h00},
{8'h2A, ypbpr ? 8'h19 : 8'h00},
{8'h2B, ypbpr ? 8'hB2 : 8'h00},
{8'h2C, ypbpr ? 8'h08 : limited[0] ? 8'h0D : 8'h0E},
{8'h2D, ypbpr ? 8'h2D : limited[0] ? 8'hBC : 8'hFE},
{8'h2E, ypbpr ? 8'h08 : 8'h01},
{8'h2F, 8'h00},
{8'h28, ypbpr ? 8'h1D : 8'h00}, // CSC Channel C.
{8'h29, ypbpr ? 8'hAE : 8'h00},
{8'h2A, ypbpr ? 8'h1B : 8'h00},
{8'h2B, ypbpr ? 8'h73 : 8'h00},
{8'h2C, ypbpr ? 8'h06 : limited[0] ? 8'h0D : 8'h0E},
{8'h2D, ypbpr ? 8'hDF : limited[0] ? 8'hBC : 8'hFE},
{8'h2E, ypbpr ? 8'h07 : 8'h01},
{8'h2F, ypbpr ? 8'hE7 : 8'h00},
{8'h3B, 8'b0000_0000}, // Pixel repetition [6:5] b00 AUTO. [4:3] b00 x1 mult of input clock. [2:1] b00 x1 pixel rep to send to HDMI Rx.

View File

@@ -126,7 +126,8 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
output reg [32:0] TIMESTAMP,
// UART flags
input [15:0] uart_mode,
output reg [7:0] uart_mode,
output reg [31:0] uart_speed,
// ps2 keyboard emulation
output ps2_kbd_clk_out,
@@ -248,6 +249,8 @@ always@(posedge clk_sys) begin : uio_block
reg old_status_set = 0;
reg old_info = 0;
reg [7:0] info_n = 0;
reg [15:0] tmp1;
reg [7:0] tmp2;
old_status_set <= status_set;
if(~old_status_set & status_set) begin
@@ -453,9 +456,6 @@ always@(posedge clk_sys) begin : uio_block
//RTC
'h24: TIMESTAMP[(byte_cnt-6'd1)<<4 +:16] <= io_din;
//UART flags
'h28: io_dout <= uart_mode;
//status set
'h29: if(!byte_cnt[MAX_W:3]) begin
case(byte_cnt[2:0])
@@ -479,6 +479,15 @@ always@(posedge clk_sys) begin : uio_block
{gamma_wr, gamma_value} <= {1'b1,io_din[7:0]};
if (byte_cnt[1:0] == 3) byte_cnt <= 1;
end
// UART
'h3b: if(!byte_cnt[MAX_W:2]) begin
case(byte_cnt[1:0])
1: tmp2 <= io_din[7:0];
2: tmp1 <= io_din;
3: {uart_speed, uart_mode} <= {io_din, tmp1, tmp2};
endcase
end
endcase
end
end

283
sys/mt32pi.sv Normal file
View File

@@ -0,0 +1,283 @@
//
// Communication module to MT32-pi (external MIDI emulator on RPi)
// (C) 2020 Sorgelig, Kitrinx
//
// https://github.com/dwhinham/mt32-pi
//
module mt32pi
(
input CLK_AUDIO,
input CLK_VIDEO,
input CE_PIXEL,
input VGA_VS,
input VGA_DE,
input [6:0] USER_IN,
output [6:0] USER_OUT,
input reset,
input midi_tx,
output midi_rx,
output reg [15:0] mt32_i2s_r,
output reg [15:0] mt32_i2s_l,
output reg mt32_available,
input mt32_mode_req,
input [1:0] mt32_rom_req,
input [7:0] mt32_sf_req,
output reg [7:0] mt32_mode,
output reg [7:0] mt32_rom,
output reg [7:0] mt32_sf,
output reg mt32_newmode,
output reg mt32_lcd_en,
output reg mt32_lcd_pix,
output reg mt32_lcd_update
);
//
// Pin | USB Name | Signal
// ----+----------+--------------
// 0 | D+ | I/O I2C_SDA / RX (midi in)
// 1 | D- | O TX (midi out)
// 2 | TX- | I I2S_WS (1 == right)
// 3 | GND_d | I I2C_SCL
// 4 | RX+ | I I2S_BCLK
// 5 | RX- | I I2S_DAT
// 6 | TX+ | - none
//
assign USER_OUT[0] = sda_out;
assign USER_OUT[1] = midi_tx;
assign USER_OUT[6:2] = '1;
//
// crossed/straight cable selection
//
generate
genvar i;
for(i = 0; i<2; i++) begin : clk_rate
wire clk_in = i ? USER_IN[6] : USER_IN[4];
reg [4:0] cnt;
always @(posedge CLK_AUDIO) begin : clkr
reg clk_sr, clk, old_clk;
reg [4:0] cnt_tmp;
clk_sr <= clk_in;
if (clk_sr == clk_in) clk <= clk_sr;
if(~&cnt_tmp) cnt_tmp <= cnt_tmp + 1'd1;
else cnt <= '1;
old_clk <= clk;
if(~old_clk & clk) begin
cnt <= cnt_tmp;
cnt_tmp <= 0;
end
end
end
reg crossed;
always @(posedge CLK_AUDIO) crossed <= (clk_rate[0].cnt <= clk_rate[1].cnt);
endgenerate
wire i2s_ws = crossed ? USER_IN[2] : USER_IN[5];
wire i2s_data = crossed ? USER_IN[5] : USER_IN[2];
wire i2s_bclk = crossed ? USER_IN[4] : USER_IN[6];
assign midi_rx = ~mt32_available ? USER_IN[0] : crossed ? USER_IN[6] : USER_IN[4];
//
// i2s receiver
//
always @(posedge CLK_AUDIO) begin : i2s_proc
reg [15:0] i2s_buf = 0;
reg [4:0] i2s_cnt = 0;
reg clk_sr;
reg i2s_clk = 0;
reg old_clk, old_ws;
reg i2s_next = 0;
// Debounce clock
clk_sr <= i2s_bclk;
if (clk_sr == i2s_bclk) i2s_clk <= clk_sr;
// Latch data and ws on rising edge
old_clk <= i2s_clk;
if (i2s_clk && ~old_clk) begin
if (~i2s_cnt[4]) begin
i2s_cnt <= i2s_cnt + 1'd1;
i2s_buf[~i2s_cnt[3:0]] <= i2s_data;
end
// Word Select will change 1 clock before the new word starts
old_ws <= i2s_ws;
if (old_ws != i2s_ws) i2s_next <= 1;
end
if (i2s_next) begin
i2s_next <= 0;
i2s_cnt <= 0;
i2s_buf <= 0;
if (i2s_ws) mt32_i2s_l <= i2s_buf;
else mt32_i2s_r <= i2s_buf;
end
if (reset) begin
i2s_buf <= 0;
mt32_i2s_l <= 0;
mt32_i2s_r <= 0;
end
end
//
// i2c slave
//
reg sda_out;
reg [7:0] lcd_data[1024];
reg lcd_sz;
reg reset_r = 0;
wire [7:0] mode_req = reset_r ? 8'hA0 : mt32_mode_req ? 8'hA2 : 8'hA1;
wire [7:0] rom_req = {6'd0, mt32_rom_req};
always @(posedge CLK_AUDIO) begin : i2c_slave
reg sda_sr, scl_sr;
reg old_sda, old_scl;
reg sda, scl;
reg [7:0] tmp;
reg [3:0] cnt = 0;
reg [10:0] bcnt = 0;
reg ack;
reg i2c_rw;
reg disp, dispdata;
reg [2:0] div;
reg old_reset;
old_reset <= reset;
if(old_reset & ~reset) sda_out <= 1;
div <= div + 1'd1;
if(!div) begin
sda_sr <= USER_IN[0];
if(sda_sr == USER_IN[0]) sda <= sda_sr;
old_sda <= sda;
scl_sr <= USER_IN[3];
if(scl_sr == USER_IN[3]) scl <= scl_sr;
old_scl <= scl;
//start
if(old_scl & scl & old_sda & ~sda) begin
cnt <= 9;
bcnt <= 0;
ack <= 0;
i2c_rw <= 0;
disp <= 0;
dispdata <= 0;
end
//stop
if(old_scl & scl & ~old_sda & sda) begin
cnt <= 0;
if(dispdata) begin
lcd_sz <= ~bcnt[9];
mt32_lcd_update <= ~mt32_lcd_update;
end
end
//data latch
if(~old_scl && scl && cnt) begin
tmp <= {tmp[6:0], sda};
cnt <= cnt - 1'd1;
end
if(!cnt) sda_out <= 1;
//data set
if(old_scl && ~scl) begin
sda_out <= 1;
if(cnt == 1) begin
if(!bcnt) begin
if(tmp[7:1] == 'h45 || tmp[7:1] == 'h3c) begin
disp <= (tmp[7:1] == 'h3c);
sda_out <= 0;
mt32_available <= 1;
ack <= 1;
i2c_rw <= tmp[0];
bcnt <= bcnt + 1'd1;
cnt <= 10;
end
else begin
// wrong address, stop
cnt <= 0;
end
end
else if(ack) begin
if(~i2c_rw) begin
if(disp) begin
if(bcnt == 1) dispdata <= (tmp[7:6] == 2'b01);
else if(dispdata) lcd_data[bcnt[9:0] - 2'd2] <= tmp;
end
else begin
if(bcnt == 1) mt32_mode <= tmp;
if(bcnt == 2) mt32_rom <= tmp;
if(bcnt == 3) mt32_sf <= tmp;
if(bcnt == 3) mt32_newmode <= ~mt32_newmode;
end
end
if(~&bcnt) bcnt <= bcnt + 1'd1;
sda_out <= 0;
cnt <= 10;
end
end
else if(i2c_rw && ack && cnt && ~disp) begin
if(bcnt == 1) sda_out <= mode_req[cnt[2:0] - 2'd2];
if(bcnt == 2) sda_out <= rom_req[cnt[2:0] - 2'd2];
if(bcnt == 3) sda_out <= mt32_sf_req[cnt[2:0] - 2'd2];
if(bcnt == 3) reset_r <= 0;
end
end
end
if(reset) begin
reset_r <= 1;
mt32_available <= 0;
end
end
always @(posedge CLK_VIDEO) begin
reg old_de, old_vs;
reg [7:0] hcnt;
reg [6:0] vcnt;
reg [7:0] sh;
if(CE_PIXEL) begin
old_de <= VGA_DE;
old_vs <= VGA_VS;
if(~&hcnt) hcnt <= hcnt + 1'd1;
sh <= (sh << 1) | (~old_de & VGA_DE);
if(sh[7]) hcnt <= 0;
if(old_de & ~VGA_DE & ~&vcnt) vcnt <= vcnt + 1'd1;
if(~old_vs & VGA_VS) vcnt <= 0;
mt32_lcd_en <= mt32_available & ~hcnt[7] && (lcd_sz ? !vcnt[6] : !vcnt[6:5]);
mt32_lcd_pix <= lcd_data[{vcnt[5:3],hcnt[6:0]}][vcnt[2:0]];
end
end
endmodule

View File

@@ -347,7 +347,14 @@ always @(posedge clk_spi) begin
'h4a: reply <= 0; // ok
// CMD12: STOP_TRANSMISSION
'h4c: reply <= 0; // ok
'h4c: reply <= 0; // ok
// CMD13: SEND_STATUS
'h4d: begin
reply <= 'h00; // ok
reply0 <='h00;
reply_len <= 1;
end
// CMD16: SET_BLOCKLEN
'h50: begin

View File

@@ -67,6 +67,8 @@ reg spdif_out_q;
reg [5:0] parity_count_q;
reg channel_status_bit;
//-----------------------------------------------------------------
// Subframe Counter
//-----------------------------------------------------------------
@@ -142,7 +144,7 @@ assign subframe_w[28] = 1'b0; // Valid
assign subframe_w[29] = 1'b0;
// Timeslots 30 = Channel status bit
assign subframe_w[30] = 1'b0;
assign subframe_w[30] = channel_status_bit ; //was constant 1'b0 enabling copy-bit;
// Timeslots 31 = Even Parity bit (31:4)
assign subframe_w[31] = 1'b0;
@@ -150,9 +152,9 @@ assign subframe_w[31] = 1'b0;
//-----------------------------------------------------------------
// Preamble
//-----------------------------------------------------------------
localparam PREAMBLE_Z = 8'b00010111;
localparam PREAMBLE_Y = 8'b00100111;
localparam PREAMBLE_X = 8'b01000111;
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;
@@ -168,6 +170,15 @@ begin
// Left Channel (but not start of block)?
else
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;
else if (subframe_count_q[8:1] == 8'd15) // frame 15 => 0 = no indication, 1 = original media
channel_status_bit = 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;
else
channel_status_bit = 1'b0; // everything else defaults to 0
end
always @ (posedge rst_i or posedge clk_i )

View File

@@ -20,8 +20,10 @@ set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) a
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) iir_filter.v ]
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ltc2308.sv ]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ]
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 ]

View File

@@ -21,29 +21,30 @@ set_clock_groups -exclusive \
set_false_path -from [get_ports {KEY*}]
set_false_path -from [get_ports {BTN_*}]
set_false_path -to [get_ports {LED_*}]
set_false_path -to [get_ports {VGA_*}]
set_false_path -to [get_ports {AUDIO_SPDIF}]
set_false_path -to [get_ports {AUDIO_L}]
set_false_path -to [get_ports {AUDIO_R}]
set_false_path -to {cfg[*]}
set_false_path -to [get_ports {LED_*}]
set_false_path -to [get_ports {VGA_*}]
set_false_path -to [get_ports {AUDIO_SPDIF}]
set_false_path -to [get_ports {AUDIO_L}]
set_false_path -to [get_ports {AUDIO_R}]
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 {wcalc[*] hcalc[*]}
set_false_path -to {width[*] height[*]}
set_multicycle_path -to {*_osd|osd_vcnt*} -setup 2
set_multicycle_path -to {*_osd|osd_vcnt*} -hold 1
set_false_path -to {*_osd|v_cnt*}
set_false_path -to {*_osd|v_osd_start*}
set_false_path -to {*_osd|v_info_start*}
set_false_path -to {*_osd|h_osd_start*}
set_false_path -to {*_osd|v_cnt*}
set_false_path -to {*_osd|v_osd_start*}
set_false_path -to {*_osd|v_info_start*}
set_false_path -to {*_osd|h_osd_start*}
set_false_path -from {*_osd|v_osd_start*}
set_false_path -from {*_osd|v_info_start*}
set_false_path -from {*_osd|h_osd_start*}
set_false_path -from {*_osd|rot*}
set_false_path -from {*_osd|dsp_width*}
set_false_path -to {*_osd|half}
set_false_path -to {*_osd|half}
set_false_path -to {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]}
set_false_path -from {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]}
@@ -51,4 +52,11 @@ set_false_path -to {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*]
set_false_path -from {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*] LFB_HMAX[*] LFB_VMIN[*] LFB_VMAX[*]}
set_false_path -to {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
set_false_path -from {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
set_false_path -from {aflt_* acx* acy* areset*}
set_false_path -from {aflt_* acx* acy* areset* arc*}
set_false_path -from {vs_line*}
set_false_path -from {ascal|o_ihsize*}
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}

View File

@@ -287,7 +287,7 @@ cyclonev_hps_interface_mpu_general_purpose h2f_gp
reg [15:0] cfg;
reg cfg_set = 0;
wire vga_fb = cfg[12];
wire vga_fb = cfg[12] | vga_force_scaler;
wire [1:0] hdmi_limited = {cfg[11],cfg[8]};
`ifdef DEBUG_NOHDMI
@@ -303,7 +303,7 @@ wire ypbpr_en = cfg[5];
wire io_osd_vga = io_ss1 & ~io_ss2;
`ifndef DUAL_SDRAM
wire sog = cfg[9];
wire vga_scaler = cfg[2];
wire vga_scaler = cfg[2] | vga_force_scaler;
`endif
reg cfg_custom_t = 0;
@@ -316,7 +316,7 @@ reg [6:0] coef_addr;
reg [8:0] coef_data;
reg coef_wr = 0;
wire [7:0] ARX, ARY;
wire[11:0] ARX, ARY;
reg [11:0] VSET = 0, HSET = 0;
reg FREESCALE = 0;
reg [2:0] scaler_flt;
@@ -337,6 +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;
always@(posedge clk_sys) begin
reg [7:0] cmd;
@@ -455,6 +459,15 @@ always@(posedge clk_sys) begin
14: acy2[23:16] <= io_din[7:0];
endcase
end
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];
endcase
end
end
end
@@ -778,9 +791,30 @@ always @(posedge clk_vid) begin
reg [11:0] videoh;
reg [11:0] height;
reg [11:0] width;
reg [11:0] arx;
reg [11:0] ary;
height <= (VSET && (VSET < HEIGHT)) ? VSET : HEIGHT;
width <= (HSET && (HSET < WIDTH)) ? HSET : WIDTH;
if(!ARY) begin
if(ARX == 1) begin
arx <= arc1x;
ary <= arc1y;
end
else if(ARX == 2) begin
arx <= arc2x;
ary <= arc2y;
end
else begin
arx <= 0;
ary <= 0;
end
end
else begin
arx <= ARX;
ary <= ARY;
end
state <= state + 1'd1;
case(state)
@@ -791,18 +825,20 @@ always @(posedge clk_vid) begin
vmax <= LFB_VMAX;
state<= 0;
end
else if(ARX && ARY && !FREESCALE) begin
wcalc <= (height*ARX)/ARY;
hcalc <= (width*ARY)/ARX;
end
else begin
else if(FREESCALE || !arx || !ary) begin
wcalc <= width;
hcalc <= height;
end
else begin
wcalc <= (height*arx)/ary;
hcalc <= (width*ary)/arx;
end
6: begin
videow <= (wcalc > width) ? width : wcalc[11:0];
videoh <= (hcalc > height) ? height : hcalc[11:0];
end
7: begin
hmin <= ((WIDTH - videow)>>1);
hmax <= ((WIDTH - videow)>>1) + videow - 1'd1;
@@ -1174,24 +1210,45 @@ wire vga_cs_osd;
csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);
`ifndef DUAL_SDRAM
wire [23:0] vga_o;
vga_out vga_out
wire [23:0] vgas_o;
wire vgas_hs, vgas_vs, vgas_cs;
vga_out vga_scaler_out
(
.ypbpr_full(0),
.clk(clk_hdmi),
.ypbpr_en(ypbpr_en),
.dout(vga_o),
.din((vga_fb | vga_scaler) ? {24{hdmi_de_osd}} & hdmi_data_osd : vga_data_osd)
.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 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] vga_o;
wire vga_hs, vga_vs, vga_cs;
vga_out vga_out
(
.clk(clk_vid),
.ypbpr_en(ypbpr_en),
.hsync(vga_hs_osd),
.vsync(vga_vs_osd),
.csync(vga_cs_osd),
.dout(vga_o),
.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 : ~vs1;
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : csync_en ? ~cs1 : ~hs1;
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;
@@ -1335,6 +1392,7 @@ wire [7:0] r_out, g_out, b_out, hr_out, hg_out, hb_out;
wire vs_fix, hs_fix, de_emu, vs_emu, hs_emu, f1;
wire hvs_fix, hhs_fix, hde_emu;
wire clk_vid, ce_pix, clk_ihdmi, ce_hpix;
wire vga_force_scaler;
`ifdef USE_DDRAM
wire ram_clk;
@@ -1422,6 +1480,7 @@ emu emu
.VGA_VS(vs_emu),
.VGA_DE(de_emu),
.VGA_F1(f1),
.VGA_SCALER(vga_force_scaler),
.CLK_VIDEO(clk_vid),
.CE_PIXEL(ce_pix),

View File

@@ -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;

View File

@@ -1,44 +1,20 @@
module vga_out
(
input ypbpr_full,
input clk,
input ypbpr_en,
input [23:0] din,
output [23:0] dout
);
input hsync,
input vsync,
input csync,
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
};
input [23:0] din,
output [23:0] dout,
output reg hsync_o,
output reg vsync_o,
output reg csync_o
);
wire [5:0] red = din[23:18];
wire [5:0] green = din[15:10];
@@ -49,17 +25,27 @@ wire [5:0] blue = din[7:2];
// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B)
// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B)
wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
wire [18:0] pb_8 = 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});
wire [18:0] pr_8 = 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});
reg [18:0] y_2, pb_2, pr_2;
reg [7:0] y, pb, pr;
reg [23:0] din2, din3;
reg hsync2, vsync2, csync2;
always @(posedge clk) begin
y_2 <= 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
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});
wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
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];
assign dout[23:16] = ypbpr_en ? {(ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]), 2'b00} : din[23:16];
assign dout[15:8] = ypbpr_en ? {(ypbpr_full ? yuv_full[y -8'd16] : y[7:2]), 2'b00} : din[15:8];
assign dout[7:0] = ypbpr_en ? {(ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]), 2'b00} : din[7:0];
hsync_o <= hsync2; hsync2 <= hsync;
vsync_o <= vsync2; vsync2 <= vsync;
csync_o <= csync2; csync2 <= csync;
din2 <= din;
din3 <= din2;
end
assign dout = ypbpr_en ? {pr, y, pb} : din3;
endmodule