Update sys. Support for custom AR.

This commit is contained in:
sorgelig
2021-02-06 22:14:45 +08:00
parent 1379386e2a
commit 621e13071a
26 changed files with 3027 additions and 1012 deletions

View File

@ -24,6 +24,13 @@
`define USE_SDRAM
`endif
`ifndef USE_DDRAM
`ifdef USE_FB
`define USE_DDRAM
`endif
`endif
module sys_top
(
/////////// CLOCK //////////
@ -236,7 +243,10 @@ wire io_ss0 = gp_outr[18];
wire io_ss1 = gp_outr[19];
wire io_ss2 = gp_outr[20];
`ifndef DEBUG_NOHDMI
wire io_osd_hdmi = io_ss1 & ~io_ss0;
`endif
wire io_fpga = ~io_ss1 & io_ss0;
wire io_uio = ~io_ss1 & io_ss2;
@ -276,11 +286,16 @@ cyclonev_hps_interface_mpu_general_purpose h2f_gp
reg [15:0] cfg;
reg cfg_got = 0;
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
wire direct_video = 1;
`else
wire direct_video = cfg[10];
`endif
wire dvi_mode = cfg[7];
wire audio_96k = cfg[6];
wire csync_en = cfg[3];
@ -288,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;
@ -301,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;
@ -312,12 +327,28 @@ reg vs_wait = 0;
reg [11:0] vs_line = 0;
reg scaler_out = 0;
reg [31:0] aflt_rate = 7056000;
reg [39:0] acx = 4258969;
reg [7:0] acx0 = 3;
reg [7:0] acx1 = 3;
reg [7:0] acx2 = 1;
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;
reg has_cmd;
reg old_strobe;
reg [7:0] cnt = 0;
reg vs_d0,vs_d1,vs_d2;
reg [4:0] acx_att;
old_strobe <= io_strobe;
coef_wr <= 0;
@ -325,6 +356,9 @@ always@(posedge clk_sys) begin
if(~io_uio) begin
has_cmd <= 0;
cmd <= 0;
areset <= 0;
acx_att <= 0;
acx <= acx >> acx_att;
end
else
if(~old_strobe & io_strobe) begin
@ -333,6 +367,17 @@ always@(posedge clk_sys) begin
cmd <= io_din[7:0];
cnt <= 0;
if(io_din[7:0] == 'h30) vs_wait <= 1;
if(io_din[7:0] == 'h39) begin
aflt_rate <= 7056000;
acx <= 4258969;
acx0 <= 3;
acx1 <= 3;
acx2 <= 1;
acy0 <= -24'd6216759;
acy1 <= 24'd6143386;
acy2 <= -24'd2023767;
areset <= 1;
end
end
else begin
if(cmd == 1) begin
@ -354,6 +399,7 @@ always@(posedge clk_sys) begin
6: if(VS != io_din[11:0]) VS <= io_din[11:0];
7: if(VBP != io_din[11:0]) VBP <= io_din[11:0];
endcase
`ifndef DEBUG_NOHDMI
if(cnt == 1) begin
cfg_custom_p1 <= 0;
cfg_custom_p2 <= 0;
@ -369,20 +415,21 @@ always@(posedge clk_sys) begin
cnt[2:0] <= 3'b100;
end
if(cnt == 8) {lowlat,cfg_dis} <= io_din[15:14];
`endif
end
end
if(cmd == 'h2F) begin
cnt <= cnt + 1'd1;
case(cnt[3:0])
0: {FB_EN,FB_FLT,FB_FMT} <= {io_din[15], io_din[14], io_din[5:0]};
1: FB_BASE[15:0] <= io_din[15:0];
2: FB_BASE[31:16] <= io_din[15:0];
3: FB_WIDTH <= io_din[11:0];
4: FB_HEIGHT <= io_din[11:0];
5: FB_HMIN <= io_din[11:0];
6: FB_HMAX <= io_din[11:0];
7: FB_VMIN <= io_din[11:0];
8: FB_VMAX <= io_din[11:0];
0: {LFB_EN,LFB_FLT,LFB_FMT} <= {io_din[15], io_din[14], io_din[5:0]};
1: LFB_BASE[15:0] <= io_din[15:0];
2: LFB_BASE[31:16] <= io_din[15:0];
3: LFB_WIDTH <= io_din[11:0];
4: LFB_HEIGHT <= io_din[11:0];
5: LFB_HMIN <= io_din[11:0];
6: LFB_HMAX <= io_din[11:0];
7: LFB_VMIN <= io_din[11:0];
8: LFB_VMAX <= io_din[11:0];
endcase
end
if(cmd == 'h25) {led_overtake, led_state} <= io_din;
@ -392,6 +439,35 @@ always@(posedge clk_sys) begin
if(cmd == 'h2B) scaler_flt <= io_din[2:0];
if(cmd == 'h37) {FREESCALE,HSET} <= {io_din[15],io_din[11:0]};
if(cmd == 'h38) vs_line <= io_din[11:0];
if(cmd == 'h39) begin
cnt <= cnt + 1'd1;
case(cnt[3:0])
0: acx_att <= io_din[4:0];
1: aflt_rate[15:0] <= io_din;
2: aflt_rate[31:16] <= io_din;
3: acx[15:0] <= io_din;
4: acx[31:16] <= io_din;
5: acx[39:32] <= io_din[7:0];
6: acx0 <= io_din[7:0];
7: acx1 <= io_din[7:0];
8: acx2 <= io_din[7:0];
9: acy0[15:0] <= io_din;
10: acy0[23:16] <= io_din[7:0];
11: acy1[15:0] <= io_din;
12: acy1[23:16] <= io_din[7:0];
13: acy2[15:0] <= io_din;
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
@ -402,16 +478,6 @@ always@(posedge clk_sys) begin
if(~vs_d2 & vs_d1) vs_wait <= 0;
end
always @(posedge clk_sys) begin
reg vsd, vsd2;
if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set;
else begin
vsd <= HDMI_TX_VS;
vsd2 <= vsd;
if(~vsd2 & vsd) cfg_got <= cfg_set;
end
end
cyclonev_hps_interface_peripheral_uart uart
(
.ri(0)
@ -465,14 +531,11 @@ always @(posedge FPGA_CLK2_50) begin
resetd2 <= resetd;
end
wire clk_100m;
wire clk_hdmi = hdmi_clk_out;
wire clk_audio = FPGA_CLK3_50;
wire clk_pal = FPGA_CLK3_50;
//////////////////// SYSTEM MEMORY & SCALER /////////////////////////
wire reset;
wire clk_100m;
sysmem_lite sysmem
(
//Reset/Clock
@ -562,6 +625,8 @@ ddr_svc ddr_svc
.ch1_ready(pal_wr)
);
wire clk_pal = clk_audio;
wire [27:0] vbuf_address;
wire [7:0] vbuf_burstcount;
@ -574,11 +639,17 @@ wire [15:0] vbuf_byteenable;
wire vbuf_write;
wire [23:0] hdmi_data;
wire hdmi_vs, hdmi_hs, hdmi_de;
wire hdmi_vs, hdmi_hs, hdmi_de, hdmi_vbl;
`ifndef DEBUG_NOHDMI
wire clk_hdmi = hdmi_clk_out;
ascal
#(
.RAMBASE(32'h20000000),
`ifndef USE_FB
.PALETTE2("false"),
`endif
.N_DW(128),
.N_AW(28)
)
@ -611,6 +682,7 @@ ascal
.o_hs (hdmi_hs),
.o_vs (hdmi_vs),
.o_de (hdmi_de),
.o_vbl (hdmi_vbl),
.o_lltune (lltune),
.htotal (WIDTH + HFP + HBP + HS),
.hsstart (WIDTH + HFP),
@ -625,22 +697,32 @@ ascal
.vmin (vmin),
.vmax (vmax),
.mode ({~lowlat,FB_EN ? FB_FLT : |scaler_flt,2'b00}),
.mode ({~lowlat,LFB_EN ? LFB_FLT : |scaler_flt,2'b00}),
.poly_clk (clk_sys),
.poly_a (coef_addr),
.poly_dw (coef_data),
.poly_wr (coef_wr),
.pal_clk (clk_pal),
.pal_dw (pal_d),
.pal_a (pal_a),
.pal_wr (pal_wr),
.pal1_clk (clk_pal),
.pal1_dw (pal_d),
.pal1_a (pal_a),
.pal1_wr (pal_wr),
`ifdef USE_FB
.pal2_clk (fb_pal_clk),
.pal2_dw (fb_pal_d),
.pal2_dr (fb_pal_q),
.pal2_a (fb_pal_a),
.pal2_wr (fb_pal_wr),
.pal_n (fb_en),
`endif
.o_fb_ena (FB_EN),
.o_fb_hsize (FB_WIDTH),
.o_fb_vsize (FB_HEIGHT),
.o_fb_format (FB_FMT),
.o_fb_base (FB_BASE),
.o_fb_stride (FB_STRIDE),
.avl_clk (clk_100m),
.avl_waitrequest (vbuf_waitrequest),
@ -653,17 +735,48 @@ ascal
.avl_read (vbuf_read),
.avl_byteenable (vbuf_byteenable)
);
`endif
reg LFB_EN = 0;
reg LFB_FLT = 0;
reg [5:0] LFB_FMT = 0;
reg [11:0] LFB_WIDTH = 0;
reg [11:0] LFB_HEIGHT = 0;
reg [11:0] LFB_HMIN = 0;
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 FB_EN = 0;
reg FB_FLT = 0;
reg [5:0] FB_FMT = 0;
reg [11:0] FB_WIDTH = 0;
reg [11:0] FB_HEIGHT = 0;
reg [11:0] FB_HMIN = 0;
reg [11:0] FB_HMAX = 0;
reg [11:0] FB_VMIN = 0;
reg [11:0] FB_VMAX = 0;
reg [31:0] FB_BASE = 0;
reg [13:0] FB_STRIDE = 0;
always @(posedge clk_sys) begin
FB_EN <= LFB_EN | fb_en;
if(LFB_EN) begin
FB_FMT <= LFB_FMT;
FB_WIDTH <= LFB_WIDTH;
FB_HEIGHT <= LFB_HEIGHT;
FB_BASE <= LFB_BASE;
FB_STRIDE <= 0;
end
else begin
FB_FMT <= fb_fmt;
FB_WIDTH <= fb_width;
FB_HEIGHT <= fb_height;
FB_BASE <= fb_base;
FB_STRIDE <= fb_stride;
end
end
`ifdef USE_FB
reg fb_vbl;
always @(posedge clk_vid) fb_vbl <= hdmi_vbl;
`endif
reg [11:0] hmin;
reg [11:0] hmax;
@ -678,31 +791,54 @@ 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)
0: if(FB_EN) begin
hmin <= FB_HMIN;
vmin <= FB_VMIN;
hmax <= FB_HMAX;
vmax <= FB_VMAX;
0: if(LFB_EN) begin
hmin <= LFB_HMIN;
vmin <= LFB_VMIN;
hmax <= LFB_HMAX;
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;
@ -712,8 +848,8 @@ always @(posedge clk_vid) begin
endcase
end
`ifndef DEBUG_NOHDMI
wire [15:0] lltune;
pll_hdmi_adj pll_hdmi_adj
(
.clk(FPGA_CLK1_50),
@ -731,6 +867,9 @@ pll_hdmi_adj pll_hdmi_adj
.o_address(cfg_address),
.o_writedata(cfg_data)
);
`else
assign led_locked = 0;
`endif
wire [63:0] pal_data;
wire [47:0] pal_d = {pal_data[55:32], pal_data[23:0]};
@ -740,17 +879,19 @@ wire pal_wr;
reg [28:0] pal_addr;
reg pal_req = 0;
always @(posedge clk_pal) begin
reg old_vs;
reg old_vs1, old_vs2;
pal_addr <= FB_BASE[31:3] - 29'd512;
pal_addr <= LFB_BASE[31:3] - 29'd512;
old_vs <= hdmi_vs;
if(~old_vs & hdmi_vs & ~FB_FMT[2] & FB_FMT[1] & FB_FMT[0] & FB_EN) pal_req <= ~pal_req;
old_vs1 <= hdmi_vs;
old_vs2 <= old_vs1;
if(~old_vs2 & old_vs1 & ~FB_FMT[2] & FB_FMT[1] & FB_FMT[0] & FB_EN) pal_req <= ~pal_req;
end
///////////////////////// HDMI output /////////////////////////////////
`ifndef DEBUG_NOHDMI
wire hdmi_clk_out;
pll_hdmi pll_hdmi
(
@ -760,6 +901,7 @@ pll_hdmi pll_hdmi
.reconfig_from_pll(reconfig_from_pll),
.outclk_0(hdmi_clk_out)
);
`endif
//1920x1080@60 PCLK=148.5MHz CEA
reg [11:0] WIDTH = 1920;
@ -781,6 +923,7 @@ reg adj_write;
reg [5:0] adj_address;
reg [31:0] adj_data;
`ifndef DEBUG_NOHDMI
pll_cfg pll_cfg
(
.mgmt_clk(FPGA_CLK1_50),
@ -795,8 +938,18 @@ pll_cfg pll_cfg
.reconfig_from_pll(reconfig_from_pll)
);
reg cfg_ready = 0;
reg cfg_got = 0;
always @(posedge clk_sys) begin
reg vsd, vsd2;
if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set;
else begin
vsd <= HDMI_TX_VS;
vsd2 <= vsd;
if(~vsd2 & vsd) cfg_got <= cfg_set;
end
end
reg cfg_ready = 0;
always @(posedge FPGA_CLK1_50) begin
reg gotd = 0, gotd2 = 0;
reg custd = 0, custd2 = 0;
@ -825,6 +978,12 @@ always @(posedge FPGA_CLK1_50) begin
if(old_wait & ~adj_waitrequest & gotd) cfg_ready <= 1;
end
`else
wire cfg_ready = 1;
`endif
wire hdmi_config_done;
hdmi_config hdmi_config
(
@ -841,14 +1000,39 @@ 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;
`ifdef USE_FB
reg dis_output;
always @(posedge clk_hdmi) begin
reg dis;
dis <= fb_force_blank;
dis_output <= dis;
end
`else
wire dis_output = 0;
`endif
scanlines #(1) HDMI_scanlines
(
.clk(clk_hdmi),
.scanlines(scanlines),
.din(hdmi_data),
.din(dis_output ? 24'd0 : hdmi_data),
.hs_in(hdmi_hs),
.vs_in(hdmi_vs),
.de_in(hdmi_de),
@ -861,6 +1045,7 @@ scanlines #(1) HDMI_scanlines
wire [23:0] hdmi_data_osd;
wire hdmi_de_osd, hdmi_vs_osd, hdmi_hs_osd;
osd hdmi_osd
(
.clk_sys(clk_sys),
@ -884,6 +1069,7 @@ osd hdmi_osd
.osd_status(osd_status)
`endif
);
`endif
wire hdmi_cs_osd;
csync csync_hdmi(clk_hdmi, hdmi_hs_osd, hdmi_vs_osd, hdmi_cs_osd);
@ -930,12 +1116,16 @@ always @(posedge clk_vid) begin
end
wire hdmi_tx_clk;
`ifndef DEBUG_NOHDMI
cyclonev_clkselect hdmi_clk_sw
(
.clkselect({1'b1, ~vga_fb & direct_video}),
.inclk({clk_vid, hdmi_clk_out, 2'b00}),
.outclk(hdmi_tx_clk)
);
`else
assign hdmi_tx_clk = clk_vid;
`endif
altddio_out
#(
@ -1032,24 +1222,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;
@ -1082,65 +1293,60 @@ end
assign SDCD_SPDIF =(SW[3] & ~spdif) ? 1'b0 : 1'bZ;
`ifndef DUAL_SDRAM
wire anl,anr;
wire analog_l, analog_r;
assign AUDIO_SPDIF = SW[3] ? 1'bZ : SW[0] ? HDMI_LRCLK : spdif;
assign AUDIO_R = SW[3] ? 1'bZ : SW[0] ? HDMI_I2S : anr;
assign AUDIO_L = SW[3] ? 1'bZ : SW[0] ? HDMI_SCLK : anl;
assign AUDIO_R = SW[3] ? 1'bZ : SW[0] ? HDMI_I2S : analog_r;
assign AUDIO_L = SW[3] ? 1'bZ : SW[0] ? HDMI_SCLK : analog_l;
`endif
assign HDMI_MCLK = 0;
assign HDMI_MCLK = clk_audio;
wire clk_audio;
wire [15:0] audio_l, audio_l_pre;
aud_mix_top audmix_l
pll_audio pll_audio
(
.clk(clk_audio),
.att(vol_att),
.mix(audio_mix),
.is_signed(audio_s),
.core_audio(audio_ls),
.pre_in(audio_r_pre),
.linux_audio(alsa_l),
.pre_out(audio_l_pre),
.out(audio_l)
);
wire [15:0] audio_r, audio_r_pre;
aud_mix_top audmix_r
(
.clk(clk_audio),
.att(vol_att),
.mix(audio_mix),
.is_signed(audio_s),
.core_audio(audio_rs),
.pre_in(audio_l_pre),
.linux_audio(alsa_r),
.pre_out(audio_r_pre),
.out(audio_r)
.refclk(FPGA_CLK3_50),
.rst(0),
.outclk_0(clk_audio)
);
wire spdif;
audio_out audio_out
(
.reset(reset),
.reset(reset | areset),
.clk(clk_audio),
.att(vol_att),
.mix(audio_mix),
.sample_rate(audio_96k),
.left_in(audio_l),
.right_in(audio_r),
.flt_rate(aflt_rate),
.cx(acx),
.cx0(acx0),
.cx1(acx1),
.cx2(acx2),
.cy0(acy0),
.cy1(acy1),
.cy2(acy2),
.is_signed(audio_s),
.core_l(audio_l),
.core_r(audio_r),
.alsa_l(alsa_l),
.alsa_r(alsa_r),
.i2s_bclk(HDMI_SCLK),
.i2s_lrclk(HDMI_LRCLK),
.i2s_data(HDMI_I2S),
`ifndef DUAL_SDRAM
.dac_l(anl),
.dac_r(anr),
.dac_l(analog_l),
.dac_r(analog_r),
`endif
.spdif(spdif)
);
wire [28:0] alsa_address;
wire [63:0] alsa_readdata;
wire alsa_ready;
@ -1168,7 +1374,6 @@ alsa alsa
.pcm_r(alsa_r)
);
//////////////// User I/O (USB 3.0 connector) /////////////////////////
assign USER_IO[0] = !user_out[0] ? 1'b0 : 1'bZ;
@ -1191,7 +1396,7 @@ assign user_in[6] = USER_IO[6];
/////////////////// User module connection ////////////////////////////
wire clk_sys;
wire [15:0] audio_ls, audio_rs;
wire [15:0] audio_l, audio_r;
wire audio_s;
wire [1:0] audio_mix;
wire [1:0] scanlines;
@ -1199,6 +1404,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;
@ -1227,24 +1433,20 @@ wire [6:0] user_out, user_in;
assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = {39'bZ};
`endif
`ifdef ARCADE_SYS
wire hvs_emu, hhs_emu;
sync_fix hdmi_sync_v(clk_ihdmi, hvs_emu, hvs_fix);
sync_fix hdmi_sync_h(clk_ihdmi, hhs_emu, hhs_fix);
assign clk_ihdmi= clk_vid;
assign ce_hpix = ce_pix;
assign hr_out = r_out;
assign hg_out = g_out;
assign hb_out = b_out;
assign hhs_fix = hs_fix;
assign hvs_fix = vs_fix;
assign hde_emu = de_emu;
`ifdef ARCADE_SYS
assign audio_mix = 0;
assign {ADC_SCK, ADC_SDI, ADC_CONVST} = 0;
assign btn = 0;
`else
assign clk_ihdmi= clk_vid;
assign ce_hpix = ce_pix;
assign hr_out = r_out;
assign hg_out = g_out;
assign hb_out = b_out;
assign hhs_fix = hs_fix;
assign hvs_fix = vs_fix;
assign hde_emu = de_emu;
wire uart_dtr;
wire uart_dsr;
wire uart_cts;
@ -1254,6 +1456,28 @@ assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQM
wire osd_status;
`endif
wire fb_en;
wire [4:0] fb_fmt;
wire [11:0] fb_width;
wire [11:0] fb_height;
wire [31:0] fb_base;
wire [13:0] fb_stride;
`ifdef USE_FB
wire fb_pal_clk;
wire [7:0] fb_pal_a;
wire [23:0] fb_pal_d;
wire [23:0] fb_pal_q;
wire fb_pal_wr;
wire fb_force_blank;
`else
assign fb_en = 0;
assign fb_fmt = 0;
assign fb_width = 0;
assign fb_height = 0;
assign fb_base = 0;
assign fb_stride = 0;
`endif
emu emu
(
@ -1268,40 +1492,46 @@ emu emu
.VGA_VS(vs_emu),
.VGA_DE(de_emu),
.VGA_F1(f1),
.VGA_SCALER(vga_force_scaler),
`ifdef ARCADE_SYS
.VGA_CLK(clk_vid),
.VGA_CE(ce_pix),
.HDMI_CLK(clk_ihdmi),
.HDMI_CE(ce_hpix),
.HDMI_R(hr_out),
.HDMI_G(hg_out),
.HDMI_B(hb_out),
.HDMI_HS(hhs_emu),
.HDMI_VS(hvs_emu),
.HDMI_DE(hde_emu),
.HDMI_SL(scanlines),
.HDMI_ARX(ARX),
.HDMI_ARY(ARY),
`else
.CLK_VIDEO(clk_vid),
.CE_PIXEL(ce_pix),
.VGA_SL(scanlines),
.VIDEO_ARX(ARX),
.VIDEO_ARY(ARY),
.AUDIO_MIX(audio_mix),
.ADC_BUS({ADC_SCK,ADC_SDO,ADC_SDI,ADC_CONVST}),
`ifdef USE_FB
.FB_EN(fb_en),
.FB_FORMAT(fb_fmt),
.FB_WIDTH(fb_width),
.FB_HEIGHT(fb_height),
.FB_BASE(fb_base),
.FB_STRIDE(fb_stride),
.FB_VBL(fb_vbl),
.FB_LL(lowlat),
.FB_FORCE_BLANK(fb_force_blank),
.FB_PAL_CLK (fb_pal_clk),
.FB_PAL_ADDR(fb_pal_a),
.FB_PAL_DOUT(fb_pal_d),
.FB_PAL_DIN (fb_pal_q),
.FB_PAL_WR (fb_pal_wr),
`endif
.LED_USER(led_user),
.LED_POWER(led_power),
.LED_DISK(led_disk),
.AUDIO_L(audio_ls),
.AUDIO_R(audio_rs),
.CLK_AUDIO(clk_audio),
.AUDIO_L(audio_l),
.AUDIO_R(audio_r),
.AUDIO_S(audio_s),
`ifndef ARCADE_SYS
.AUDIO_MIX(audio_mix),
.ADC_BUS({ADC_SCK,ADC_SDO,ADC_SDI,ADC_CONVST}),
`endif
`ifdef USE_DDRAM
.DDRAM_CLK(ram_clk),
.DDRAM_ADDR(ram_address),
@ -1401,56 +1631,6 @@ endmodule
/////////////////////////////////////////////////////////////////////
module aud_mix_top
(
input clk,
input [4:0] att,
input [1:0] mix,
input is_signed,
input [15:0] core_audio,
input [15:0] linux_audio,
input [15:0] pre_in,
output reg [15:0] pre_out,
output reg [15:0] out
);
reg [15:0] ca;
always @(posedge clk) begin
reg [15:0] d1,d2,d3;
d1 <= core_audio; d2<=d1; d3<=d2;
if(d2 == d3) ca <= d2;
end
always @(posedge clk) begin
reg signed [16:0] a1, a2, a3, a4;
a1 <= is_signed ? {ca[15],ca} : {2'b00,ca[15:1]};
a2 <= a1 + {linux_audio[15],linux_audio};
pre_out <= a2[16:1];
case(mix)
0: a3 <= a2;
1: a3 <= $signed(a2) - $signed(a2[16:3]) + $signed(pre_in[15:2]);
2: a3 <= $signed(a2) - $signed(a2[16:2]) + $signed(pre_in[15:1]);
3: a3 <= {a2[16],a2[16:1]} + {pre_in[15],pre_in};
endcase
if(att[4]) a4 <= 0;
else a4 <= a3 >>> att[3:0];
//clamping
out <= ^a4[16:15] ? {a4[16],{15{a4[15]}}} : a4[15:0];
end
endmodule
/////////////////////////////////////////////////////////////////////
// CSync generation
// Shifts HSync left by 1 HSync period during VSync