diff --git a/cores/ht1080z/ht1080z.qsf b/cores/ht1080z/ht1080z.qsf index 445d9ce..d5329f9 100644 --- a/cores/ht1080z/ht1080z.qsf +++ b/cores/ht1080z/ht1080z.qsf @@ -41,7 +41,7 @@ # ======================== set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1 set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:40:24 MAY 17, 2014" -set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name SMART_RECOMPILE ON @@ -118,7 +118,6 @@ set_location_assignment PIN_66 -to SDRAM_nWE set_location_assignment PIN_59 -to SDRAM_nCS set_location_assignment PIN_33 -to SDRAM_CKE set_location_assignment PIN_43 -to SDRAM_CLK -set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component" # Classic Timing Assignments # ========================== @@ -329,7 +328,6 @@ set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON set_location_assignment PLL_1 -to clkmgr|altpll_component|auto_generated|pll1 set_global_assignment -name USE_SIGNALTAP_FILE output_files/vid.stp set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON -set_global_assignment -name QIP_FILE mist/mist.qip set_global_assignment -name VHDL_FILE videoctrl.vhd set_global_assignment -name VHDL_FILE YM2149_linmix.vhd set_global_assignment -name VERILOG_FILE sdram.v @@ -341,4 +339,5 @@ set_global_assignment -name VHDL_FILE ht1080z.vhd set_global_assignment -name QIP_FILE pll.qip set_global_assignment -name SIGNALTAP_FILE output_files/vid.stp set_global_assignment -name QIP_FILE t80/T80.qip +set_global_assignment -name QIP_FILE "../../mist-modules/mist.qip" set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/cores/ht1080z/ht1080z.sdc b/cores/ht1080z/ht1080z.sdc index d00dcde..15b1b44 100644 --- a/cores/ht1080z/ht1080z.sdc +++ b/cores/ht1080z/ht1080z.sdc @@ -36,14 +36,11 @@ derive_clock_uncertainty set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[*]}] # SDRAM delays -set_input_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 6.4 [get_ports SDRAM_DQ[*]] -set_input_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -min 3.2 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -max 6.4 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -min 3.2 [get_ports SDRAM_DQ[*]] -set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] -set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] - -set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_CLK}] -set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_CLK}] +set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] +set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] # Some relaxed constrain to the VGA pins. The signals should arrive together, the delay is not really important. set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 0 [get_ports {VGA_*}] diff --git a/cores/ht1080z/ht1080z.vhd b/cores/ht1080z/ht1080z.vhd index 175db0c..bbb879b 100644 --- a/cores/ht1080z/ht1080z.vhd +++ b/cores/ht1080z/ht1080z.vhd @@ -83,18 +83,18 @@ end ht1080z; architecture Behavioral of ht1080z is component data_io - port ( sck, ss, sdi : in std_logic; + port ( + clk_sys : in std_logic; - -- download info - downloading : out std_logic; - --size : out std_logic_vector(24 downto 0); - index : out std_logic_vector(4 downto 0); - - -- external ram interface - clk : in std_logic; - wr : out std_logic; - addr : out std_logic_vector(24 downto 0); - data : out std_logic_vector(7 downto 0) + SPI_SCK, SPI_SS2, SPI_DI : in std_logic; + -- download info + ioctl_download : out std_logic; + ioctl_index : out std_logic_vector(4 downto 0); + + -- external ram interface + ioctl_wr : out std_logic; + ioctl_addr : out std_logic_vector(24 downto 0); + ioctl_dout : out std_logic_vector(7 downto 0) ); end component data_io; @@ -161,6 +161,7 @@ signal autores : std_logic; signal scandoubler_disable : std_logic; signal ypbpr : std_logic; +signal no_csync : std_logic; signal buttons : std_logic_vector(1 downto 0); signal PS2CLK : std_logic; @@ -403,40 +404,42 @@ begin user_io: work.mist.user_io generic map (STRLEN => CONF_STR'length) port map ( - clk_sys => clk42m, + clk_sys => clk42m, conf_str => to_slv(CONF_STR), - SPI_CLK => SPI_SCK , + SPI_CLK => SPI_SCK , SPI_SS_IO => CONF_DATA0 , SPI_MISO => SPI_DO , SPI_MOSI => SPI_DI , - status => status, - buttons => buttons, + status => status, + buttons => buttons, - -- ps2 interface - ps2_kbd_clk => ps2CLK, - ps2_kbd_data => ps2DAT, - ps2_mouse_clk => mps2CLK, - ps2_mouse_data => mps2DAT, + -- ps2 interface + ps2_kbd_clk => ps2CLK, + ps2_kbd_data => ps2DAT, + ps2_mouse_clk => mps2CLK, + ps2_mouse_data => mps2DAT, - joystick_0 => joy0, - joystick_1 => joy1, + joystick_0 => joy0, + joystick_1 => joy1, - scandoubler_disable => scandoubler_disable, - ypbpr => ypbpr + scandoubler_disable => scandoubler_disable, + ypbpr => ypbpr, + no_csync => no_csync ); mist_video : work.mist.mist_video - generic map ( - SD_HCNT_WIDTH => 10, - OSD_COLOR => "110") - port map ( - clk_sys => clk42m, - scandoubler_disable => scandoubler_disable, - scanlines => status(2 downto 1), - ypbpr => ypbpr, - rotate => "00", + generic map ( + SD_HCNT_WIDTH => 10, + OSD_COLOR => "110") + port map ( + clk_sys => clk42m, + scandoubler_disable => scandoubler_disable, + scanlines => status(2 downto 1), + ypbpr => ypbpr, + no_csync => no_csync, + rotate => "00", SPI_SCK => SPI_SCK, SPI_SS3 => SPI_SS3, SPI_DI => SPI_DI, @@ -450,10 +453,10 @@ mist_video : work.mist.mist_video VGA_R => VGA_R, VGA_G => VGA_G, VGA_B => VGA_B, - VGA_HS => VGA_HS, - VGA_VS => VGA_VS + VGA_HS => VGA_HS, + VGA_VS => VGA_VS ); - + sdram_inst : sdram port map( sd_data => SDRAM_DQ, sd_addr => SDRAM_A, @@ -485,22 +488,20 @@ mist_video : work.mist.mist_video SDRAM_DQMH <= sdram_dqm(1); SDRAM_DQML <= sdram_dqm(0); - dataio : data_io port map ( - sck => SPI_SCK, - ss => SPI_SS2, - sdi => SPI_DI, + clk_sys => clk42m, + SPI_SCK => SPI_SCK, + SPI_SS2 => SPI_SS2, + SPI_DI => SPI_DI, - downloading => dn_go, - --size => ioctl_size, - index => dn_idx, + ioctl_download => dn_go, + ioctl_index => dn_idx, - -- ram interface - clk => clk42m, - wr => dn_wr, - addr => dn_addr, - data => dn_data + -- ram interface + ioctl_wr => dn_wr, + ioctl_addr => dn_addr, + ioctl_dout => dn_data ); process(clk42m) @@ -510,7 +511,11 @@ mist_video : work.mist.mist_video if dn_wr='1' then dn_wr_new <= '1'; dn_data_r <= dn_data; - dn_addr_r <= dn_addr; + if dn_idx = x"00" then + dn_addr_r <= dn_addr; + else + dn_addr_r <= dn_addr + x"10000"; + end if; end if; if clkref = '1' then if dn_wr_new = '1' then diff --git a/cores/ht1080z/mist/dac.vhd b/cores/ht1080z/mist/dac.vhd deleted file mode 100644 index 9b209e5..0000000 --- a/cores/ht1080z/mist/dac.vhd +++ /dev/null @@ -1,71 +0,0 @@ -------------------------------------------------------------------------------- --- --- Delta-Sigma DAC --- --- $Id: dac.vhd,v 1.1 2006/05/10 20:57:06 arnim Exp $ --- --- Refer to Xilinx Application Note XAPP154. --- --- This DAC requires an external RC low-pass filter: --- --- dac_o 0---XXXXX---+---0 analog audio --- 3k3 | --- === 4n7 --- | --- GND --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -entity dac is - - generic ( - msbi_g : integer := 7 - ); - port ( - clk_i : in std_logic; - res_n_i : in std_logic; - dac_i : in std_logic_vector(msbi_g downto 0); - dac_o : out std_logic - ); - -end dac; - -library ieee; -use ieee.numeric_std.all; - -architecture rtl of dac is - - signal DACout_q : std_logic; - signal DeltaAdder_s, - SigmaAdder_s, - SigmaLatch_q, - DeltaB_s : unsigned(msbi_g+2 downto 0); - -begin - - DeltaB_s(msbi_g+2 downto msbi_g+1) <= SigmaLatch_q(msbi_g+2) & - SigmaLatch_q(msbi_g+2); - DeltaB_s(msbi_g downto 0) <= (others => '0'); - - DeltaAdder_s <= unsigned('0' & '0' & dac_i) + DeltaB_s; - - SigmaAdder_s <= DeltaAdder_s + SigmaLatch_q; - - seq: process (clk_i, res_n_i) - begin - if res_n_i = '0' then - SigmaLatch_q <= to_unsigned(2**(msbi_g+1), SigmaLatch_q'length); - DACout_q <= '0'; - - elsif clk_i'event and clk_i = '1' then - SigmaLatch_q <= SigmaAdder_s; - DACout_q <= SigmaLatch_q(msbi_g+2); - end if; - end process seq; - - dac_o <= DACout_q; - -end rtl; diff --git a/cores/ht1080z/mist/data_io.v b/cores/ht1080z/mist/data_io.v deleted file mode 100644 index 1aae9d7..0000000 --- a/cores/ht1080z/mist/data_io.v +++ /dev/null @@ -1,121 +0,0 @@ -// -// data_io.v -// -// io controller writable ram for the MiST board -// http://code.google.com/p/mist-board/ -// -// ZX Spectrum adapted version -// -// Copyright (c) 2015 Till Harbaum -// -// 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 -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This source file is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -module data_io ( - // io controller spi interface - input sck, - input ss, - input sdi, - - output downloading, // signal indicating an active download - output reg [4:0] index, // menu index used to upload the file - - // external ram interface - input clk, - output reg wr, - output reg [24:0] addr, - output reg [7:0] data -); - -// ********************************************************************************* -// spi client -// ********************************************************************************* - -// this core supports only the display related OSD commands -// of the minimig -reg [6:0] sbuf; -reg [7:0] cmd; -reg [4:0] cnt; -reg rclk; - -localparam UIO_FILE_TX = 8'h53; -localparam UIO_FILE_TX_DAT = 8'h54; -localparam UIO_FILE_INDEX = 8'h55; - -assign downloading = downloading_reg; -reg downloading_reg = 1'b0; - -// data_io has its own SPI interface to the io controller -always@(posedge sck, posedge ss) begin - if(ss == 1'b1) - cnt <= 5'd0; - else begin - rclk <= 1'b0; - - // don't shift in last bit. It is evaluated directly - // when writing to ram - if(cnt != 15) - sbuf <= { sbuf[5:0], sdi}; - - // increase target address after write - if(rclk) - addr <= addr + 1'd1; - - // count 0-7 8-15 8-15 ... - if(cnt < 15) cnt <= cnt + 4'd1; - else cnt <= 4'd8; - - // finished command byte - if(cnt == 7) - cmd <= {sbuf, sdi}; - - // prepare/end transmission - if((cmd == UIO_FILE_TX) && (cnt == 15)) begin - // prepare - if(sdi) begin - //addr <= 25'd0; - // pppppppp - // xxxx....xxxx.... - if (index==5'b00000) addr <= 25'b0000000000000000000000000; - else addr <= 25'b0000000010000000000000000; - //addr <= 25'b0000000001100000000000000; - downloading_reg <= 1'b1; - end else - downloading_reg <= 1'b0; - end - - // command 0x54: UIO_FILE_TX - if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin - data <= {sbuf, sdi}; - rclk <= 1'b1; - end - - // expose file (menu) index - if((cmd == UIO_FILE_INDEX) && (cnt == 15)) - index <= {sbuf[3:0], sdi}; - end -end - -reg rclkD, rclkD2; -always@(posedge clk) begin - // bring rclk from spi clock domain into c64 clock domain - rclkD <= rclk; - rclkD2 <= rclkD; - wr <= 1'b0; - - if(rclkD && !rclkD2) - wr <= 1'b1; -end - -endmodule diff --git a/cores/ht1080z/mist/mist.qip b/cores/ht1080z/mist/mist.qip deleted file mode 100644 index 5aefaaa..0000000 --- a/cores/ht1080z/mist/mist.qip +++ /dev/null @@ -1,8 +0,0 @@ -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) mist.vhd] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) user_io.v] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) data_io.v] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mist_video.v] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.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) rgb2ypbpr.sv] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) dac.vhd] diff --git a/cores/ht1080z/mist/mist.vhd b/cores/ht1080z/mist/mist.vhd deleted file mode 100644 index 711d630..0000000 --- a/cores/ht1080z/mist/mist.vhd +++ /dev/null @@ -1,102 +0,0 @@ --- user_io --- Interface to the MiST IO Controller - --- mist_video --- A video pipeline for MiST. Just insert between the core video output and the VGA pins --- Provides an optional scandoubler, a rotateable OSD and (optional) RGb->YPbPr conversion - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -package mist is - -component user_io - generic(STRLEN : integer := 0 ); - port ( - clk_sys : in std_logic; - clk_sd : in std_logic := '0'; - SPI_CLK, SPI_SS_IO, SPI_MOSI :in std_logic; - SPI_MISO : out std_logic; - conf_str : in std_logic_vector(8*STRLEN-1 downto 0); - joystick_0 : out std_logic_vector(31 downto 0); - joystick_1 : out std_logic_vector(31 downto 0); - joystick_2 : out std_logic_vector(31 downto 0); - joystick_3 : out std_logic_vector(31 downto 0); - joystick_4 : out std_logic_vector(31 downto 0); - joystick_analog_0 : out std_logic_vector(15 downto 0); - joystick_analog_1 : out std_logic_vector(15 downto 0); - status: out std_logic_vector(31 downto 0); - switches : out std_logic_vector(1 downto 0); - buttons : out std_logic_vector(1 downto 0); - scandoubler_disable : out std_logic; - ypbpr : out std_logic; - - sd_lba : in std_logic_vector(31 downto 0) := (others => '0'); - sd_rd : in std_logic := '0'; - sd_wr : in std_logic := '0'; - sd_ack : out std_logic; - sd_ack_conf : out std_logic; - sd_conf : in std_logic := '0'; - sd_sdhc : in std_logic := '1'; - img_size : out std_logic_vector(31 downto 0); - img_mounted : out std_logic; - - sd_buff_addr : out std_logic_vector(8 downto 0); - sd_dout : out std_logic_vector(7 downto 0); - sd_din : in std_logic_vector(7 downto 0) := (others => '0'); - sd_dout_strobe : out std_logic; - sd_din_strobe : out std_logic; - - ps2_kbd_clk : out std_logic; - ps2_kbd_data : out std_logic; - key_pressed : out std_logic; - key_extended : out std_logic; - key_code : out std_logic_vector(7 downto 0); - key_strobe : out std_logic; - - ps2_mouse_clk : out std_logic; - ps2_mouse_data : out std_logic; - mouse_x : out signed(8 downto 0); - mouse_y : out signed(8 downto 0); - mouse_flags : out std_logic_vector(7 downto 0); -- YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn - mouse_strobe : out std_logic - ); -end component user_io; - -component mist_video - generic ( - OSD_COLOR : std_logic_vector(2 downto 0) := "110"; - OSD_X_OFFSET : std_logic_vector(9 downto 0) := (others => '0'); - OSD_Y_OFFSET : std_logic_vector(9 downto 0) := (others => '0'); - SD_HCNT_WIDTH: integer := 9; - COLOR_DEPTH : integer := 6 - ); - port ( - clk_sys : in std_logic; - - SPI_SCK : in std_logic; - SPI_SS3 : in std_logic; - SPI_DI : in std_logic; - - scanlines : in std_logic_vector(1 downto 0); - ce_divider : in std_logic := '0'; - scandoubler_disable : in std_logic; - ypbpr : in std_logic; - rotate : in std_logic_vector(1 downto 0); - - HSync : in std_logic; - VSync : in std_logic; - R : in std_logic_vector(COLOR_DEPTH-1 downto 0); - G : in std_logic_vector(COLOR_DEPTH-1 downto 0); - B : in std_logic_vector(COLOR_DEPTH-1 downto 0); - - VGA_HS : out std_logic; - VGA_VS : out std_logic; - VGA_R : out std_logic_vector(5 downto 0); - VGA_G : out std_logic_vector(5 downto 0); - VGA_B : out std_logic_vector(5 downto 0) - ); -end component mist_video; - -end package; \ No newline at end of file diff --git a/cores/ht1080z/mist/mist_video.v b/cores/ht1080z/mist/mist_video.v deleted file mode 100644 index b5eda35..0000000 --- a/cores/ht1080z/mist/mist_video.v +++ /dev/null @@ -1,143 +0,0 @@ -// A video pipeline for MiST. Just insert between the core video output and the VGA pins -// Provides an optional scandoubler, a rotateable OSD and (optional) RGb->YPbPr conversion - -module mist_video -( - // master clock - // it should be 4x (or 2x) pixel clock for the scandoubler - input clk_sys, - - // OSD SPI interface - input SPI_SCK, - input SPI_SS3, - input SPI_DI, - - // scanlines (00-none 01-25% 10-50% 11-75%) - input [1:0] scanlines, - - // non-scandoubled pixel clock divider 0 - clk_sys/4, 1 - clk_sys/2 - input ce_divider, - - // 0 = HVSync 31KHz, 1 = CSync 15KHz - input scandoubler_disable, - // YPbPr always uses composite sync - input ypbpr, - // Rotate OSD [0] - rotate [1] - left or right - input [1:0] rotate, - - // video in - input [COLOR_DEPTH-1:0] R, - input [COLOR_DEPTH-1:0] G, - input [COLOR_DEPTH-1:0] B, - - input HSync, - input VSync, - - // MiST video output signals - output [5:0] VGA_R, - output [5:0] VGA_G, - output [5:0] VGA_B, - output VGA_VS, - output VGA_HS -); - -parameter OSD_COLOR = 3'd4; -parameter OSD_X_OFFSET = 10'd0; -parameter OSD_Y_OFFSET = 10'd0; -parameter SD_HCNT_WIDTH = 9; -parameter COLOR_DEPTH = 6; // 1-6 - -wire [5:0] SD_R_O; -wire [5:0] SD_G_O; -wire [5:0] SD_B_O; -wire SD_HS_O; -wire SD_VS_O; - -reg [5:0] R_full; -reg [5:0] G_full; -reg [5:0] B_full; - -always @(*) begin - if (COLOR_DEPTH == 6) begin - R_full = R; - G_full = G; - B_full = B; - end else if (COLOR_DEPTH == 2) begin - R_full = {3{R}}; - G_full = {3{G}}; - B_full = {3{B}}; - end else if (COLOR_DEPTH == 1) begin - R_full = {6{R}}; - G_full = {6{G}}; - B_full = {6{B}}; - end else begin - R_full = { R, R[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] }; - G_full = { G, G[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] }; - B_full = { B, B[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] }; - end -end - -scandoubler #(SD_HCNT_WIDTH, COLOR_DEPTH) scandoubler -( - .clk_sys ( clk_sys ), - .scanlines ( scanlines ), - .ce_divider ( ce_divider ), - .hs_in ( HSync ), - .vs_in ( VSync ), - .r_in ( R ), - .g_in ( G ), - .b_in ( B ), - .hs_out ( SD_HS_O ), - .vs_out ( SD_VS_O ), - .r_out ( SD_R_O ), - .g_out ( SD_G_O ), - .b_out ( SD_B_O ) -); - -wire [5:0] osd_r_o; -wire [5:0] osd_g_o; -wire [5:0] osd_b_o; - -osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd -( - .clk_sys ( clk_sys ), - .rotate ( rotate ), - .SPI_DI ( SPI_DI ), - .SPI_SCK ( SPI_SCK ), - .SPI_SS3 ( SPI_SS3 ), - .R_in ( scandoubler_disable ? R_full : SD_R_O ), - .G_in ( scandoubler_disable ? G_full : SD_G_O ), - .B_in ( scandoubler_disable ? B_full : SD_B_O ), - .HSync ( scandoubler_disable ? HSync : SD_HS_O ), - .VSync ( scandoubler_disable ? VSync : SD_VS_O ), - .R_out ( osd_r_o ), - .G_out ( osd_g_o ), - .B_out ( osd_b_o ) -); - -wire [5:0] y, pb, pr; - -rgb2ypbpr rgb2ypbpr -( - .red ( osd_r_o ), - .green ( osd_g_o ), - .blue ( osd_b_o ), - .y ( y ), - .pb ( pb ), - .pr ( pr ) -); - -assign VGA_R = ypbpr?pr:osd_r_o; -assign VGA_G = ypbpr? y:osd_g_o; -assign VGA_B = ypbpr?pb:osd_b_o; - -wire cs = scandoubler_disable ? ~(HSync ^ VSync) : ~(SD_HS_O ^ SD_VS_O); -wire hs = scandoubler_disable ? HSync : SD_HS_O; -wire vs = scandoubler_disable ? VSync : SD_VS_O; - -// a minimig vga->scart cable expects a composite sync signal on the VGA_HS output. -// and VCC on VGA_VS (to switch into rgb mode) -assign VGA_HS = (scandoubler_disable || ypbpr)? cs : hs; -assign VGA_VS = (scandoubler_disable || ypbpr)? 1'b1 : vs; - -endmodule diff --git a/cores/ht1080z/mist/osd.v b/cores/ht1080z/mist/osd.v deleted file mode 100644 index 5527e72..0000000 --- a/cores/ht1080z/mist/osd.v +++ /dev/null @@ -1,195 +0,0 @@ -// A simple OSD implementation. Can be hooked up between a cores -// VGA output and the physical VGA pins - -module osd ( - // OSDs pixel clock, should be synchronous to cores pixel clock to - // avoid jitter. - input clk_sys, - - // SPI interface - input SPI_SCK, - input SPI_SS3, - input SPI_DI, - - input [1:0] rotate, //[0] - rotate [1] - left or right - - // VGA signals coming from core - input [5:0] R_in, - input [5:0] G_in, - input [5:0] B_in, - input HSync, - input VSync, - - // VGA signals going to video connector - output [5:0] R_out, - output [5:0] G_out, - output [5:0] B_out -); - -parameter OSD_X_OFFSET = 10'd0; -parameter OSD_Y_OFFSET = 10'd0; -parameter OSD_COLOR = 3'd0; - -localparam OSD_WIDTH = 10'd256; -localparam OSD_HEIGHT = 10'd128; - -// ********************************************************************************* -// spi client -// ********************************************************************************* - -// this core supports only the display related OSD commands -// of the minimig -reg osd_enable; -(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself - -// the OSD has its own SPI interface to the io controller -always@(posedge SPI_SCK, posedge SPI_SS3) begin - reg [4:0] cnt; - reg [10:0] bcnt; - reg [7:0] sbuf; - reg [7:0] cmd; - - if(SPI_SS3) begin - cnt <= 0; - bcnt <= 0; - end else begin - sbuf <= {sbuf[6:0], SPI_DI}; - - // 0:7 is command, rest payload - if(cnt < 15) cnt <= cnt + 1'd1; - else cnt <= 8; - - if(cnt == 7) begin - cmd <= {sbuf[6:0], SPI_DI}; - - // lower three command bits are line address - bcnt <= {sbuf[1:0], SPI_DI, 8'h00}; - - // command 0x40: OSDCMDENABLE, OSDCMDDISABLE - if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI; - end - - // command 0x20: OSDCMDWRITE - if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin - osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI}; - bcnt <= bcnt + 1'd1; - end - end -end - -// ********************************************************************************* -// video timing and sync polarity anaylsis -// ********************************************************************************* - -// horizontal counter -reg [9:0] h_cnt; -reg [9:0] hs_low, hs_high; -wire hs_pol = hs_high < hs_low; -wire [9:0] dsp_width = hs_pol ? hs_low : hs_high; - -// vertical counter -reg [9:0] v_cnt; -reg [9:0] vs_low, vs_high; -wire vs_pol = vs_high < vs_low; -wire [9:0] dsp_height = vs_pol ? vs_low : vs_high; - -wire doublescan = (dsp_height>350); - -reg ce_pix; -always @(negedge clk_sys) begin - integer cnt = 0; - integer pixsz, pixcnt; - reg hs; - - cnt <= cnt + 1; - hs <= HSync; - - pixcnt <= pixcnt + 1; - if(pixcnt == pixsz) pixcnt <= 0; - ce_pix <= !pixcnt; - - if(hs && ~HSync) begin - cnt <= 0; - pixsz <= (cnt >> 9) - 1; - pixcnt <= 0; - ce_pix <= 1; - end -end - -always @(posedge clk_sys) begin - reg hsD, hsD2; - reg vsD, vsD2; - - if(ce_pix) begin - // bring hsync into local clock domain - hsD <= HSync; - hsD2 <= hsD; - - // falling edge of HSync - if(!hsD && hsD2) begin - h_cnt <= 0; - hs_high <= h_cnt; - end - - // rising edge of HSync - else if(hsD && !hsD2) begin - h_cnt <= 0; - hs_low <= h_cnt; - v_cnt <= v_cnt + 1'd1; - end else begin - h_cnt <= h_cnt + 1'd1; - end - - vsD <= VSync; - vsD2 <= vsD; - - // falling edge of VSync - if(!vsD && vsD2) begin - v_cnt <= 0; - vs_high <= v_cnt; - end - - // rising edge of VSync - else if(vsD && !vsD2) begin - v_cnt <= 0; - vs_low <= v_cnt; - end - end -end - -// area in which OSD is being displayed -wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET; -wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH; -wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<> 1) + OSD_Y_OFFSET; -wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<= h_osd_start) && ((h_cnt + 1'd1) < h_osd_end) && - (VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); - end -end - -assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]}; -assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]}; -assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]}; - -endmodule diff --git a/cores/ht1080z/mist/rgb2ypbpr.sv b/cores/ht1080z/mist/rgb2ypbpr.sv deleted file mode 100644 index 1e1662e..0000000 --- a/cores/ht1080z/mist/rgb2ypbpr.sv +++ /dev/null @@ -1,55 +0,0 @@ -module rgb2ypbpr ( - input [5:0] red, - input [5:0] green, - input [5:0] blue, - - output [5:0] y, - output [5:0] pb, - output [5:0] pr -); - -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 [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}); - -wire [7:0] y_i = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8]; -wire [7:0] pb_i = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8]; -wire [7:0] pr_i = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8]; - -assign pr = yuv_full[pr_i - 8'd16]; -assign y = yuv_full[y_i - 8'd16]; -assign pb = yuv_full[pb_i - 8'd16]; - -endmodule diff --git a/cores/ht1080z/mist/scandoubler.v b/cores/ht1080z/mist/scandoubler.v deleted file mode 100644 index 120788c..0000000 --- a/cores/ht1080z/mist/scandoubler.v +++ /dev/null @@ -1,216 +0,0 @@ -// -// scandoubler.v -// -// Copyright (c) 2015 Till Harbaum -// -// 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 -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This source file is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// TODO: Delay vsync one line - -module scandoubler -( - // system interface - input clk_sys, - - // scanlines (00-none 01-25% 10-50% 11-75%) - input [1:0] scanlines, - input ce_divider, // 0 - 4, 1 - 2 - - // shifter video interface - input hs_in, - input vs_in, - input [COLOR_DEPTH-1:0] r_in, - input [COLOR_DEPTH-1:0] g_in, - input [COLOR_DEPTH-1:0] b_in, - - // output interface - output reg hs_out, - output reg vs_out, - output reg [5:0] r_out, - output reg [5:0] g_out, - output reg [5:0] b_out -); - -parameter HCNT_WIDTH = 9; -parameter COLOR_DEPTH = 6; - -// try to detect changes in input signal and lock input clock gate -// it - -reg [1:0] i_div; - -reg ce_x1, ce_x2; - -always @(*) begin - if (!ce_divider) begin - ce_x1 = (i_div == 2'b01); - ce_x2 = i_div[0]; - end else begin - ce_x1 = i_div[0]; - ce_x2 = 1'b1; - end -end - -always @(posedge clk_sys) begin - reg last_hs_in; - last_hs_in <= hs_in; - if(last_hs_in & !hs_in) begin - i_div <= 2'b00; - end else begin - i_div <= i_div + 2'd1; - end -end - - -// --------------------- create output signals ----------------- -// latch everything once more to make it glitch free and apply scanline effect -reg scanline; -reg [5:0] r; -reg [5:0] g; -reg [5:0] b; - -always @(*) begin - if (COLOR_DEPTH == 6) begin - b = sd_out[5:0]; - g = sd_out[11:6]; - r = sd_out[17:12]; - end else if (COLOR_DEPTH == 2) begin - b = {3{sd_out[1:0]}}; - g = {3{sd_out[3:2]}}; - r = {3{sd_out[5:4]}}; - end else if (COLOR_DEPTH == 1) begin - b = {6{sd_out[0]}}; - g = {6{sd_out[1]}}; - r = {6{sd_out[2]}}; - end else begin - b = { sd_out[COLOR_DEPTH-1:0], sd_out[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] }; - g = { sd_out[COLOR_DEPTH*2-1:COLOR_DEPTH], sd_out[COLOR_DEPTH*2-1 -:(6-COLOR_DEPTH)] }; - r = { sd_out[COLOR_DEPTH*3-1:COLOR_DEPTH*2], sd_out[COLOR_DEPTH*3-1 -:(6-COLOR_DEPTH)] }; - end -end - -always @(posedge clk_sys) begin - if(ce_x2) begin - hs_out <= hs_sd; - vs_out <= vs_in; - - // reset scanlines at every new screen - if(vs_out != vs_in) scanline <= 0; - - // toggle scanlines at begin of every hsync - if(hs_out && !hs_sd) scanline <= !scanline; - - // if no scanlines or not a scanline - if(!scanline || !scanlines) begin - r_out <= r; - g_out <= g; - b_out <= b; - end else begin - case(scanlines) - 1: begin // reduce 25% = 1/2 + 1/4 - r_out <= {1'b0, r[5:1]} + {2'b00, r[5:2] }; - g_out <= {1'b0, g[5:1]} + {2'b00, g[5:2] }; - b_out <= {1'b0, b[5:1]} + {2'b00, b[5:2] }; - end - - 2: begin // reduce 50% = 1/2 - r_out <= {1'b0, r[5:1]}; - g_out <= {1'b0, g[5:1]}; - b_out <= {1'b0, b[5:1]}; - end - - 3: begin // reduce 75% = 1/4 - r_out <= {2'b00, r[5:2]}; - g_out <= {2'b00, g[5:2]}; - b_out <= {2'b00, b[5:2]}; - end - endcase - end - end -end - -// scan doubler output register -reg [COLOR_DEPTH*3-1:0] sd_out; - -// ================================================================== -// ======================== the line buffers ======================== -// ================================================================== - -// 2 lines of 2**HCNT_WIDTH pixels 3*COLOR_DEPTH bit RGB -(* ramstyle = "no_rw_check" *) reg [COLOR_DEPTH*3-1:0] sd_buffer[2*2**HCNT_WIDTH]; - -// use alternating sd_buffers when storing/reading data -reg line_toggle; - -// total hsync time (in 16MHz cycles), hs_total reaches 1024 -reg [HCNT_WIDTH-1:0] hs_max; -reg [HCNT_WIDTH-1:0] hs_rise; -reg [HCNT_WIDTH-1:0] hcnt; - -always @(posedge clk_sys) begin - reg hsD, vsD; - - if(ce_x1) begin - hsD <= hs_in; - - // falling edge of hsync indicates start of line - if(hsD && !hs_in) begin - hs_max <= hcnt; - hcnt <= 0; - end else begin - hcnt <= hcnt + 1'd1; - end - - // save position of rising edge - if(!hsD && hs_in) hs_rise <= hcnt; - - vsD <= vs_in; - if(vsD != vs_in) line_toggle <= 0; - - // begin of incoming hsync - if(hsD && !hs_in) line_toggle <= !line_toggle; - - sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in}; - end -end - -// ================================================================== -// ==================== output timing generation ==================== -// ================================================================== - -reg [HCNT_WIDTH-1:0] sd_hcnt; -reg hs_sd; - -// timing generation runs 32 MHz (twice the input signal analysis speed) -always @(posedge clk_sys) begin - reg hsD; - - if(ce_x2) begin - hsD <= hs_in; - - // output counter synchronous to input and at twice the rate - sd_hcnt <= sd_hcnt + 1'd1; - if(hsD && !hs_in) sd_hcnt <= hs_max; - if(sd_hcnt == hs_max) sd_hcnt <= 0; - - // replicate horizontal sync at twice the speed - if(sd_hcnt == hs_max) hs_sd <= 0; - if(sd_hcnt == hs_rise) hs_sd <= 1; - - // read data from line sd_buffer - sd_out <= sd_buffer[{~line_toggle, sd_hcnt}]; - end -end - -endmodule diff --git a/cores/ht1080z/mist/user_io.v b/cores/ht1080z/mist/user_io.v deleted file mode 100644 index b5f0f69..0000000 --- a/cores/ht1080z/mist/user_io.v +++ /dev/null @@ -1,572 +0,0 @@ -// -// user_io.v -// -// user_io for the MiST board -// http://code.google.com/p/mist-board/ -// -// Copyright (c) 2014 Till Harbaum -// -// 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 -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This source file is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -// parameter STRLEN and the actual length of conf_str have to match - -module user_io #(parameter STRLEN=0, parameter PS2DIV=100) ( - input [(8*STRLEN)-1:0] conf_str, - - input clk_sys, // clock for system-related messages (kbd, joy, etc...) - input clk_sd, // clock for SD-card related messages - - input SPI_CLK, - input SPI_SS_IO, - output reg SPI_MISO, - input SPI_MOSI, - - output reg [31:0] joystick_0, - output reg [31:0] joystick_1, - output reg [31:0] joystick_2, - output reg [31:0] joystick_3, - output reg [31:0] joystick_4, - output reg [15:0] joystick_analog_0, - output reg [15:0] joystick_analog_1, - output [1:0] buttons, - output [1:0] switches, - output scandoubler_disable, - output ypbpr, - output reg [31:0] status, - - // connection to sd card emulation - input [31:0] sd_lba, - input sd_rd, - input sd_wr, - output reg sd_ack, - output reg sd_ack_conf, - input sd_conf, - input sd_sdhc, - output reg [7:0] sd_dout, // valid on rising edge of sd_dout_strobe - output reg sd_dout_strobe, - input [7:0] sd_din, - output reg sd_din_strobe, - output reg [8:0] sd_buff_addr, - - output reg img_mounted, //rising edge if a new image is mounted - output reg [31:0] img_size, // size of image in bytes - - // ps2 keyboard/mouse emulation - output ps2_kbd_clk, - output reg ps2_kbd_data, - output ps2_mouse_clk, - output reg ps2_mouse_data, - - // keyboard data - output reg key_pressed, // 1-make (pressed), 0-break (released) - output reg key_extended, // extended code - output reg [7:0] key_code, // key scan code - output reg key_strobe, // key data valid - - // mouse data - output reg [8:0] mouse_x, - output reg [8:0] mouse_y, - output reg [7:0] mouse_flags, // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn - output reg mouse_strobe, // mouse data is valid on mouse_strobe - - // serial com port - input [7:0] serial_data, - input serial_strobe -); - -reg [6:0] sbuf; -reg [7:0] cmd; -reg [2:0] bit_cnt; // counts bits 0-7 0-7 ... -reg [9:0] byte_cnt; // counts bytes -reg [7:0] but_sw; -reg [2:0] stick_idx; - -assign buttons = but_sw[1:0]; -assign switches = but_sw[3:2]; -assign scandoubler_disable = but_sw[4]; -assign ypbpr = but_sw[5]; - -// this variant of user_io is for 8 bit cores (type == a4) only -wire [7:0] core_type = 8'ha4; - -// command byte read by the io controller -wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd }; - -wire spi_sck = SPI_CLK; - -// ---------------- PS2 --------------------- -// 8 byte fifos to store ps2 bytes -localparam PS2_FIFO_BITS = 3; - -reg ps2_clk; -always @(negedge clk_sys) begin - integer cnt; - cnt <= cnt + 1'd1; - if(cnt == PS2DIV) begin - ps2_clk <= ~ps2_clk; - cnt <= 0; - end -end - -// keyboard -reg [7:0] ps2_kbd_fifo [(2**PS2_FIFO_BITS)-1:0]; -reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr; -reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr; - -// ps2 transmitter state machine -reg [3:0] ps2_kbd_tx_state; -reg [7:0] ps2_kbd_tx_byte; -reg ps2_kbd_parity; - -assign ps2_kbd_clk = ps2_clk || (ps2_kbd_tx_state == 0); - -// ps2 transmitter -// Takes a byte from the FIFO and sends it in a ps2 compliant serial format. -reg ps2_kbd_r_inc; -always@(posedge clk_sys) begin - reg ps2_clkD; - - ps2_clkD <= ps2_clk; - if (~ps2_clkD & ps2_clk) begin - ps2_kbd_r_inc <= 1'b0; - - if(ps2_kbd_r_inc) - ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1; - - // transmitter is idle? - if(ps2_kbd_tx_state == 0) begin - // data in fifo present? - if(ps2_kbd_wptr != ps2_kbd_rptr) begin - // load tx register from fifo - ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr]; - ps2_kbd_r_inc <= 1'b1; - - // reset parity - ps2_kbd_parity <= 1'b1; - - // start transmitter - ps2_kbd_tx_state <= 4'd1; - - // put start bit on data line - ps2_kbd_data <= 1'b0; // start bit is 0 - end - end else begin - - // transmission of 8 data bits - if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin - ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits - ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down - if(ps2_kbd_tx_byte[0]) - ps2_kbd_parity <= !ps2_kbd_parity; - end - - // transmission of parity - if(ps2_kbd_tx_state == 9) - ps2_kbd_data <= ps2_kbd_parity; - - // transmission of stop bit - if(ps2_kbd_tx_state == 10) - ps2_kbd_data <= 1'b1; // stop bit is 1 - - // advance state machine - if(ps2_kbd_tx_state < 11) - ps2_kbd_tx_state <= ps2_kbd_tx_state + 4'd1; - else - ps2_kbd_tx_state <= 4'd0; - end - end -end - -// mouse -reg [7:0] ps2_mouse_fifo [(2**PS2_FIFO_BITS)-1:0]; -reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr; -reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr; - -// ps2 transmitter state machine -reg [3:0] ps2_mouse_tx_state; -reg [7:0] ps2_mouse_tx_byte; -reg ps2_mouse_parity; - -assign ps2_mouse_clk = ps2_clk || (ps2_mouse_tx_state == 0); - -// ps2 transmitter -// Takes a byte from the FIFO and sends it in a ps2 compliant serial format. -reg ps2_mouse_r_inc; -always@(posedge clk_sys) begin - reg ps2_clkD; - - ps2_clkD <= ps2_clk; - if (~ps2_clkD & ps2_clk) begin - ps2_mouse_r_inc <= 1'b0; - - if(ps2_mouse_r_inc) - ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1; - - // transmitter is idle? - if(ps2_mouse_tx_state == 0) begin - // data in fifo present? - if(ps2_mouse_wptr != ps2_mouse_rptr) begin - // load tx register from fifo - ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr]; - ps2_mouse_r_inc <= 1'b1; - - // reset parity - ps2_mouse_parity <= 1'b1; - - // start transmitter - ps2_mouse_tx_state <= 4'd1; - - // put start bit on data line - ps2_mouse_data <= 1'b0; // start bit is 0 - end - end else begin - - // transmission of 8 data bits - if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin - ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits - ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down - if(ps2_mouse_tx_byte[0]) - ps2_mouse_parity <= !ps2_mouse_parity; - end - - // transmission of parity - if(ps2_mouse_tx_state == 9) - ps2_mouse_data <= ps2_mouse_parity; - - // transmission of stop bit - if(ps2_mouse_tx_state == 10) - ps2_mouse_data <= 1'b1; // stop bit is 1 - - // advance state machine - if(ps2_mouse_tx_state < 11) - ps2_mouse_tx_state <= ps2_mouse_tx_state + 4'd1; - else - ps2_mouse_tx_state <= 4'd0; - end - end -end - -// fifo to receive serial data from core to be forwarded to io controller - -// 16 byte fifo to store serial bytes -localparam SERIAL_OUT_FIFO_BITS = 6; -reg [7:0] serial_out_fifo [(2**SERIAL_OUT_FIFO_BITS)-1:0]; -reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_wptr; -reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_rptr; - -wire serial_out_data_available = serial_out_wptr != serial_out_rptr; -wire [7:0] serial_out_byte = serial_out_fifo[serial_out_rptr] /* synthesis keep */; -wire [7:0] serial_out_status = { 7'b1000000, serial_out_data_available}; - -// status[0] is reset signal from io controller and is thus used to flush -// the fifo -always @(posedge serial_strobe or posedge status[0]) begin - if(status[0] == 1) begin - serial_out_wptr <= 0; - end else begin - serial_out_fifo[serial_out_wptr] <= serial_data; - serial_out_wptr <= serial_out_wptr + 1'd1; - end -end - -always@(negedge spi_sck or posedge status[0]) begin - if(status[0] == 1) begin - serial_out_rptr <= 0; - end else begin - if((byte_cnt != 0) && (cmd == 8'h1b)) begin - // read last bit -> advance read pointer - if((bit_cnt == 7) && !byte_cnt[0] && serial_out_data_available) - serial_out_rptr <= serial_out_rptr + 1'd1; - end - end -end - - -// SPI bit and byte counters -always@(posedge spi_sck or posedge SPI_SS_IO) begin - if(SPI_SS_IO == 1) begin - bit_cnt <= 0; - byte_cnt <= 0; - end else begin - if((bit_cnt == 7)&&(~&byte_cnt)) - byte_cnt <= byte_cnt + 8'd1; - - bit_cnt <= bit_cnt + 1'd1; - end -end - -// SPI transmitter FPGA -> IO -reg [7:0] spi_byte_out; - -always@(negedge spi_sck or posedge SPI_SS_IO) begin - if(SPI_SS_IO == 1) begin - SPI_MISO <= 1'bZ; - end else begin - SPI_MISO <= spi_byte_out[~bit_cnt]; - end -end - -always@(posedge spi_sck or posedge SPI_SS_IO) begin - reg [31:0] sd_lba_r; - - if(SPI_SS_IO == 1) begin - spi_byte_out <= core_type; - end else begin - // read the command byte to choose the response - if(bit_cnt == 7) begin - if(!byte_cnt) cmd <= {sbuf, SPI_MOSI}; - - spi_byte_out <= 0; - case({(!byte_cnt) ? {sbuf, SPI_MOSI} : cmd}) - // reading config string - 8'h14: if(byte_cnt < STRLEN) spi_byte_out <= conf_str[(STRLEN - byte_cnt - 1)<<3 +:8]; - - // reading sd card status - 8'h16: if(byte_cnt == 0) begin - spi_byte_out <= sd_cmd; - sd_lba_r <= sd_lba; - end - else if(byte_cnt < 5) spi_byte_out <= sd_lba_r[(4-byte_cnt)<<3 +:8]; - - // reading sd card write data - 8'h18: spi_byte_out <= sd_din; - 8'h1b: - // send alternating flag byte and data - if(byte_cnt[0]) spi_byte_out <= serial_out_status; - else spi_byte_out <= serial_out_byte; - endcase - end - end -end - -// SPI receiver IO -> FPGA - -reg spi_receiver_strobe_r = 0; -reg spi_transfer_end_r = 1; -reg [7:0] spi_byte_in; - -// Read at spi_sck clock domain, assemble bytes for transferring to clk_sys -always@(posedge spi_sck or posedge SPI_SS_IO) begin - - if(SPI_SS_IO == 1) begin - spi_transfer_end_r <= 1; - end else begin - spi_transfer_end_r <= 0; - - if(bit_cnt != 7) - sbuf[6:0] <= { sbuf[5:0], SPI_MOSI }; - - // finished reading a byte, prepare to transfer to clk_sys - if(bit_cnt == 7) begin - spi_byte_in <= { sbuf, SPI_MOSI}; - spi_receiver_strobe_r <= ~spi_receiver_strobe_r; - end - end -end - -// Process bytes from SPI at the clk_sys domain -always @(posedge clk_sys) begin - - reg spi_receiver_strobe; - reg spi_transfer_end; - reg spi_receiver_strobeD; - reg spi_transfer_endD; - reg [7:0] acmd; - reg [7:0] abyte_cnt; // counts bytes - - reg [7:0] mouse_flags_r; - reg [7:0] mouse_x_r; - - reg key_pressed_r; - reg key_extended_r; - - //synchronize between SPI and sys clock domains - spi_receiver_strobeD <= spi_receiver_strobe_r; - spi_receiver_strobe <= spi_receiver_strobeD; - spi_transfer_endD <= spi_transfer_end_r; - spi_transfer_end <= spi_transfer_endD; - - key_strobe <= 0; - mouse_strobe <= 0; - - if (~spi_transfer_endD & spi_transfer_end) begin - abyte_cnt <= 8'd0; - end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin - - if(~&abyte_cnt) - abyte_cnt <= abyte_cnt + 8'd1; - - if(abyte_cnt == 0) begin - acmd <= spi_byte_in; - end else begin - case(acmd) - // buttons and switches - 8'h01: but_sw <= spi_byte_in; - 8'h60: if (abyte_cnt < 5) joystick_0[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; - 8'h61: if (abyte_cnt < 5) joystick_1[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; - 8'h62: if (abyte_cnt < 5) joystick_2[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; - 8'h63: if (abyte_cnt < 5) joystick_3[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; - 8'h64: if (abyte_cnt < 5) joystick_4[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; - 8'h04: begin - // store incoming ps2 mouse bytes - ps2_mouse_fifo[ps2_mouse_wptr] <= spi_byte_in; - ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1; - if (abyte_cnt == 1) mouse_flags_r <= spi_byte_in; - else if (abyte_cnt == 2) mouse_x_r <= spi_byte_in; - else if (abyte_cnt == 3) begin - // flags: YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn - mouse_flags <= mouse_flags_r; - mouse_x <= { mouse_flags_r[4], mouse_x_r }; - mouse_y <= { mouse_flags_r[5], spi_byte_in }; - mouse_strobe <= 1; - end - end - 8'h05: begin - // store incoming ps2 keyboard bytes - ps2_kbd_fifo[ps2_kbd_wptr] <= spi_byte_in; - ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1; - if (abyte_cnt == 1) begin - key_extended_r <= 0; - key_pressed_r <= 1; - end - if (spi_byte_in == 8'he0) key_extended_r <= 1'b1; - else if (spi_byte_in == 8'hf0) key_pressed_r <= 1'b0; - else begin - key_extended <= key_extended_r; - key_pressed <= key_pressed_r || abyte_cnt == 1; - key_code <= spi_byte_in; - key_strobe <= 1'b1; - end - end - - // joystick analog - 8'h1a: begin - // first byte is joystick index - if(abyte_cnt == 1) - stick_idx <= spi_byte_in[2:0]; - else if(abyte_cnt == 2) begin - // second byte is x axis - if(stick_idx == 0) - joystick_analog_0[15:8] <= spi_byte_in; - else if(stick_idx == 1) - joystick_analog_1[15:8] <= spi_byte_in; - end else if(abyte_cnt == 3) begin - // third byte is y axis - if(stick_idx == 0) - joystick_analog_0[7:0] <= spi_byte_in; - else if(stick_idx == 1) - joystick_analog_1[7:0] <= spi_byte_in; - end - end - - 8'h15: status <= spi_byte_in; - - // status, 32bit version - 8'h1e: if(abyte_cnt<5) status[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; - - endcase - end - end -end - -// Process SD-card related bytes from SPI at the clk_sd domain -always @(posedge clk_sd) begin - - reg spi_receiver_strobe; - reg spi_transfer_end; - reg spi_receiver_strobeD; - reg spi_transfer_endD; - reg sd_wrD; - reg [7:0] acmd; - reg [7:0] abyte_cnt; // counts bytes - - //synchronize between SPI and sd clock domains - spi_receiver_strobeD <= spi_receiver_strobe_r; - spi_receiver_strobe <= spi_receiver_strobeD; - spi_transfer_endD <= spi_transfer_end_r; - spi_transfer_end <= spi_transfer_endD; - - if(sd_dout_strobe) begin - sd_dout_strobe<= 0; - if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; - end - - sd_din_strobe<= 0; - sd_wrD <= sd_wr; - // fetch the first byte immediately after the write command seen - if (~sd_wrD & sd_wr) begin - sd_buff_addr <= 0; - sd_din_strobe <= 1; - end - - img_mounted <= 0; - - if (~spi_transfer_endD & spi_transfer_end) begin - abyte_cnt <= 8'd0; - sd_ack <= 1'b0; - sd_ack_conf <= 1'b0; - sd_dout_strobe <= 1'b0; - sd_din_strobe <= 1'b0; - sd_buff_addr <= 0; - end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin - - if(~&abyte_cnt) - abyte_cnt <= abyte_cnt + 8'd1; - - if(abyte_cnt == 0) begin - acmd <= spi_byte_in; - - if(spi_byte_in == 8'h18) begin - sd_din_strobe <= 1'b1; - if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; - end - - if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18)) - sd_ack <= 1'b1; - - end else begin - case(acmd) - - // send sector IO -> FPGA - 8'h17: begin - // flag that download begins - sd_dout_strobe <= 1'b1; - sd_dout <= spi_byte_in; - end - - // send sector FPGA -> IO - 8'h18: begin - sd_din_strobe <= 1'b1; - if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; - end - - // send SD config IO -> FPGA - 8'h19: begin - // flag that download begins - sd_dout_strobe <= 1'b1; - sd_ack_conf <= 1'b1; - sd_dout <= spi_byte_in; - end - - 8'h1c: img_mounted <= 1; - - // send image info - 8'h1d: if(abyte_cnt<5) img_size[(abyte_cnt-1)<<3 +:8] <= spi_byte_in; - endcase - end - end -end - -endmodule