From 37fb0aba2621cd26859e5b5a0ec38428794f1396 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Mon, 17 Feb 2020 21:12:38 +0100 Subject: [PATCH] C16: import mist-modules, use common components --- .gitmodules | 3 + cores/c16/c16_mist.qsf | 9 +- cores/c16/c16_mist.v | 248 ++++---- cores/c16/data_io.v | 127 ----- cores/c16/osd.v | 208 ------- cores/c16/rgb2ypbpr.sv | 55 -- cores/c16/scandoubler.v | 177 ------ cores/c16/stp1.stp | 1186 --------------------------------------- cores/c16/user_io.v | 522 ----------------- mist-modules | 1 + 10 files changed, 104 insertions(+), 2432 deletions(-) create mode 100644 .gitmodules delete mode 100644 cores/c16/data_io.v delete mode 100644 cores/c16/osd.v delete mode 100644 cores/c16/rgb2ypbpr.sv delete mode 100644 cores/c16/scandoubler.v delete mode 100644 cores/c16/stp1.stp delete mode 100644 cores/c16/user_io.v create mode 160000 mist-modules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a4fe047 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "mist-modules"] + path = mist-modules + url = https://github.com/mist-devel/mist-modules.git diff --git a/cores/c16/c16_mist.qsf b/cores/c16/c16_mist.qsf index a68f417..09b3450 100644 --- a/cores/c16/c16_mist.qsf +++ b/cores/c16/c16_mist.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 @@ -348,11 +348,7 @@ set_global_assignment -name VHDL_FILE tap_fifo.vhd set_global_assignment -name VHDL_FILE c1530.vhd set_global_assignment -name VHDL_FILE gen_ram.vhd set_global_assignment -name VERILOG_FILE sigma_delta_dac.v -set_global_assignment -name VERILOG_FILE data_io.v set_global_assignment -name VERILOG_FILE sdram.v -set_global_assignment -name VERILOG_FILE osd.v -set_global_assignment -name VERILOG_FILE scandoubler.v -set_global_assignment -name VERILOG_FILE user_io.v set_global_assignment -name VERILOG_FILE ted.v set_global_assignment -name VERILOG_FILE mos8501.v set_global_assignment -name VERILOG_FILE mos6529.v @@ -363,6 +359,7 @@ set_global_assignment -name VERILOG_FILE c16_keymatrix.v set_global_assignment -name VERILOG_FILE c16.v set_global_assignment -name VERILOG_FILE ps2receiver.v set_global_assignment -name VERILOG_FILE basic_rom.v +set_global_assignment -name QIP_FILE "../../mist-modules/mist.qip" set_global_assignment -name VHDL_FILE c1541/gcr_floppy.vhd set_global_assignment -name VHDL_FILE c1541/spram.vhd set_global_assignment -name VHDL_FILE c1541/gen_rom.vhd @@ -374,8 +371,6 @@ set_global_assignment -name VHDL_FILE t65/T65_Pack.vhd set_global_assignment -name VHDL_FILE t65/T65_MCode.vhd set_global_assignment -name VHDL_FILE t65/T65_ALU.vhd set_global_assignment -name VHDL_FILE t65/T65.vhd -set_global_assignment -name SIGNALTAP_FILE output_files/stp1.stp -set_global_assignment -name SYSTEMVERILOG_FILE rgb2ypbpr.sv set_global_assignment -name QIP_FILE pll_c1541.qip set_global_assignment -name QIP_FILE pll_c16.qip set_global_assignment -name QIP_FILE rom_reconfig_pal.qip diff --git a/cores/c16/c16_mist.v b/cores/c16/c16_mist.v index 7981f41..19e6c8b 100644 --- a/cores/c16/c16_mist.v +++ b/cores/c16/c16_mist.v @@ -77,14 +77,14 @@ parameter CONF_STR = { "F,ROM,Load Kernal;", "T6,Play/Stop tape;", "O7,Tape sound,Off,On;", - "O2,Scanlines,Off,On;", + "O12,Scanlines,Off,25%,50%,75%;", "O3,Joysticks,Normal,Swapped;", "O4,Memory,64k,16k;", "O89,SID,Off,6581,8580;", "T5,Reset;" }; -parameter CONF_STR_LEN = 11+17+18+18+21+20+28+18+22+9; +parameter CONF_STR_LEN = 11+17+18+18+21+30+28+18+22+9; localparam ROM_MEM_START = 25'h10000; localparam TAP_MEM_START = 25'h20000; @@ -104,7 +104,8 @@ assign UART_TX = ~cass_motor; wire [31:0] status; wire tv15khz; wire ypbpr; -wire scanlines = status[2]; +wire no_csync; +wire [1:0] scanlines = status[2:1]; wire joystick_swap = status[3]; wire memory_16k = status[4]; wire osd_reset = status[5]; @@ -274,58 +275,54 @@ wire img_mounted; wire [8:0] sd_buff_addr; // include user_io module for arm controller communication -user_io #(.STRLEN(CONF_STR_LEN)) user_io ( - .conf_str ( CONF_STR ), +user_io #(.STRLEN(CONF_STR_LEN)) user_io ( + .conf_str ( CONF_STR ), - .clk_sys ( clk28 ), - .clk_sd ( clk32 ), + .clk_sys ( clk28 ), + .clk_sd ( clk32 ), - .SPI_CLK ( SPI_SCK ), - .SPI_SS_IO ( CONF_DATA0 ), - .SPI_MISO ( SPI_DO ), - .SPI_MOSI ( SPI_DI ), + .SPI_CLK ( SPI_SCK ), + .SPI_SS_IO ( CONF_DATA0 ), + .SPI_MISO ( SPI_DO ), + .SPI_MOSI ( SPI_DI ), - .scandoubler_disable ( tv15khz ), - .ypbpr ( ypbpr ), - .buttons ( buttons ), + .scandoubler_disable ( tv15khz ), + .ypbpr ( ypbpr ), + .no_csync ( no_csync ), + .buttons ( buttons ), - .joystick_0 ( js0 ), - .joystick_1 ( js1 ), + .joystick_0 ( js0 ), + .joystick_1 ( js1 ), - // ps2 interface - .ps2_kbd_clk ( ps2_kbd_clk ), - .ps2_kbd_data ( ps2_kbd_data ), - .ps2_mouse_clk ( ps2_mouse_clk ), - .ps2_mouse_data ( ps2_mouse_data ), + // ps2 interface + .ps2_kbd_clk ( ps2_kbd_clk ), + .ps2_kbd_data ( ps2_kbd_data ), + .ps2_mouse_clk ( ps2_mouse_clk ), + .ps2_mouse_data ( ps2_mouse_data ), - .sd_lba ( sd_lba ), - .sd_rd ( sd_rd ), - .sd_wr ( sd_wr ), - .sd_ack ( sd_ack ), - .sd_ack_conf ( sd_ack_conf ), - .sd_conf ( sd_conf ), - .sd_sdhc ( sd_sdhc ), - .sd_dout ( sd_dout ), - .sd_dout_strobe ( sd_dout_strobe ), - .sd_din ( sd_din ), - .sd_din_strobe ( sd_din_strobe ), - .sd_buff_addr ( sd_buff_addr), - .img_mounted ( img_mounted ), + .sd_lba ( sd_lba ), + .sd_rd ( sd_rd ), + .sd_wr ( sd_wr ), + .sd_ack ( sd_ack ), + .sd_ack_conf ( sd_ack_conf ), + .sd_conf ( sd_conf ), + .sd_sdhc ( sd_sdhc ), + .sd_dout ( sd_dout ), + .sd_dout_strobe ( sd_dout_strobe ), + .sd_din ( sd_din ), + .sd_din_strobe ( sd_din_strobe ), + .sd_buff_addr ( sd_buff_addr ), + .img_mounted ( img_mounted ), - .status ( status ) + .status ( status ) ); -wire sd_cs; -wire sd_dat; -wire sd_cmd; -wire sd_clk; - // --------------------------------------------------------------------------------- // ------------------------------ prg memory injection ----------------------------- // --------------------------------------------------------------------------------- wire ioctl_wr; -wire [15:0] ioctl_addr; +wire [24:0] ioctl_addr; wire [7:0] ioctl_data; wire [7:0] ioctl_index; wire ioctl_downloading; @@ -337,18 +334,18 @@ wire tap_download = ioctl_downloading && (ioctl_index == 8'h41); wire c16_wait = rom_download | prg_download; data_io data_io ( - // SPI interface - .sck ( SPI_SCK ), - .ss ( SPI_SS2 ), - .sdi ( SPI_DI ), - - // ram interface - .downloading ( ioctl_downloading ), - .index ( ioctl_index ), - .clk ( clk28 ), - .wr ( ioctl_wr ), - .a ( ioctl_addr ), - .d ( ioctl_data ) + .clk_sys ( clk28 ), + // SPI interface + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_DI ( SPI_DI ), + + // ram interface + .ioctl_download ( ioctl_downloading ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_data ) ); // magic zero page shadow registers to allow the injector to set the @@ -429,18 +426,18 @@ always @(posedge clk28) begin // data io has a byte for us if(ioctl_wr) begin if (prg_download) begin - if(ioctl_addr == 16'h0000) ioctl_sdram_addr[7:0] <= ioctl_data; - else if (ioctl_addr == 16'h0001) ioctl_sdram_addr[24:8] <= { 9'b0, ioctl_data }; + if(ioctl_addr == 0) ioctl_sdram_addr[7:0] <= ioctl_data; + else if (ioctl_addr == 25'h1) ioctl_sdram_addr[24:8] <= { 9'b0, ioctl_data }; else // io controller sent a new byte. Store it until it can be // saved in RAM ioctl_ram_wr <= 1'b1; end else if (tap_download) begin - if(ioctl_addr == 16'h0000) ioctl_sdram_addr <= TAP_MEM_START; + if(ioctl_addr == 0) ioctl_sdram_addr <= TAP_MEM_START; ioctl_ram_wr <= 1'b1; end else if (rom_download) begin - if((ioctl_index == 8'h0 && ioctl_addr == 16'h4000) || (ioctl_index == 8'h3 && ioctl_addr == 16'h0000)) ioctl_sdram_addr <= ROM_MEM_START; - if((ioctl_index == 8'h0 && ioctl_addr[15:14]) || ioctl_index == 8'h3) ioctl_ram_wr <= 1'b1; + if((ioctl_index == 8'h0 && ioctl_addr == 25'h4000) || (ioctl_index == 8'h3 && ioctl_addr == 0)) ioctl_sdram_addr <= ROM_MEM_START; + if((ioctl_index == 8'h0 && ioctl_addr[16:14] != 0) || ioctl_index == 8'h3) ioctl_ram_wr <= 1'b1; end end @@ -521,90 +518,54 @@ c1530 c1530 ); // --------------------------------------------------------------------------------- -// ------------------------------ the on screen display ---------------------------- +// ---------------------------------- video output --------------------------------- // --------------------------------------------------------------------------------- - -// in 15khz mode feed the c16 video directly into the OSD, -// bypassing the scan doubler -wire [5:0] osd_r_in = tv15khz?{c16_r, 2'b00}:video_r; -wire [5:0] osd_g_in = tv15khz?{c16_g, 2'b00}:video_g; -wire [5:0] osd_b_in = tv15khz?{c16_b, 2'b00}:video_b; -wire osd_hs_in = tv15khz?c16_hs:video_hs; -wire osd_vs_in = tv15khz?!c16_vs:video_vs; +wire hs, vs; -wire osd_clk = tv15khz?clk7:clk14; +mist_video #(.COLOR_DEPTH(4), .OSD_COLOR(3'd5), .SD_HCNT_WIDTH(10)) mist_video ( + .clk_sys ( clk28 ), -wire [5:0] red, green, blue; + // OSD SPI interface + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), -// include the on screen display -osd #(10'd11,10'd0,3'd5) osd ( - .clk_sys ( clk28 ), - .ce_pix ( osd_clk ), + // scanlines (00-none 01-25% 10-50% 11-75%) + .scanlines ( scanlines ), - // spi for OSD - .sdi ( SPI_DI ), - .sck ( SPI_SCK ), - .ss ( SPI_SS3 ), + // non-scandoubled pixel clock divider 0 - clk_sys/4, 1 - clk_sys/2 + .ce_divider ( 1'b0 ), - .red_in ( osd_r_in ), - .green_in ( osd_g_in ), - .blue_in ( osd_b_in ), - .hs_in ( osd_hs_in ), - .vs_in ( osd_vs_in ), + // 0 = HVSync 31KHz, 1 = CSync 15KHz + .scandoubler_disable ( tv15khz ), + // disable csync without scandoubler + .no_csync ( no_csync ), + // YPbPr always uses composite sync + .ypbpr ( ypbpr ), + // Rotate OSD [0] - rotate [1] - left or right + .rotate ( 2'b00 ), + // composite-like blending + .blend ( 1'b0 ), - .red_out ( red ), - .green_out ( green ), - .blue_out ( blue ) + // video in + .R ( c16_r ), + .G ( c16_g ), + .B ( c16_b ), + + .HSync ( c16_hs ), + .VSync ( ~c16_vs ), + + // MiST video output signals + .VGA_R ( VGA_R ), + .VGA_G ( VGA_G ), + .VGA_B ( VGA_B ), + .VGA_VS ( vs ), + .VGA_HS ( hs ) ); -wire [5:0] y, pb, pr; -rgb2ypbpr rgb2ypbpr ( - .red ( red ), - .green ( green ), - .blue ( blue ), - - .y ( y ), - .pb ( pb ), - .pr ( pr ) -); - -assign VGA_R = ypbpr ? pr : red; -assign VGA_G = ypbpr ? y : green; -assign VGA_B = ypbpr ? pb : blue; - -// in 15khz tv mode directly use the c16's composite sync. Otherwise the VGA -// output is driven from the sync signals generated by the scan doubler. In -// 15khz mode the VS signal is used as the RGB detect signal on the SCART -// connector and thus needs to be driven to 1 -assign VGA_HS = tv15khz ? c16_cs:(ypbpr ? ~(video_hs ^ video_vs) : video_hs); -assign VGA_VS = (tv15khz || ypbpr)?1'b1:video_vs; - -wire video_hs, video_vs; -wire [5:0] video_r; -wire [5:0] video_g; -wire [5:0] video_b; - -scandoubler scandoubler ( - // system interface - .clk_sys ( clk28 ), - - // scanlines (00-none 01-25% 10-50% 11-75%) - .scanlines ( scanlines?2'b10:2'b00 ), - - // shifter video interface - .hs_in ( c16_hs ), - .vs_in ( !c16_vs ), - .r_in ( c16_r ), - .g_in ( c16_g ), - .b_in ( c16_b ), - - // output interface - .hs_out ( video_hs ), - .vs_out ( video_vs ), - .r_out ( video_r ), - .g_out ( video_g ), - .b_out ( video_b ) -); +// Use TED generated csync @15kHz +assign VGA_HS = (~no_csync & tv15khz & ~ypbpr) ? c16_cs : hs; +assign VGA_VS = (~no_csync & tv15khz & ~ypbpr) ? 1'b1 : vs; // --------------------------------------------------------------------------------- // ------------------------------------ c16 core ----------------------------------- @@ -631,14 +592,14 @@ reg [13:0] rom_dl_addr; wire ioctl_rom_wr = rom_download && ioctl_wr; always @(negedge clk28) begin - reg last_ioctl_rom_wr; + reg last_ioctl_rom_wr; last_ioctl_rom_wr <= ioctl_rom_wr; if(ioctl_rom_wr && !last_ioctl_rom_wr) begin rom_dl_data <= ioctl_data; rom_dl_addr <= ioctl_addr[13:0]; - c1541_dl_wr <= !ioctl_addr[15:14] && ioctl_index == 5'd0; - kernal_dl_wr <= ioctl_addr[15:14] == 2'd1 || ioctl_index == 5'd3; - basic_dl_wr <= ioctl_addr[15:14] == 2'd2 && ioctl_index == 5'd0; + c1541_dl_wr <= ioctl_addr[16:14] == 3'd0 && ioctl_index == 8'h0; + kernal_dl_wr <= ioctl_addr[16:14] == 3'd1 || ioctl_index == 8'h3; + basic_dl_wr <= ioctl_addr[16:14] == 3'd2 && ioctl_index == 8'h0; end else { kernal_dl_wr, basic_dl_wr, c1541_dl_wr } <= 0; end @@ -724,19 +685,6 @@ C16 #(.INTERNAL_ROM(0)) c16 ( wire pll_locked = pll_c1541_locked && pll_c16_locked; wire ntsc = ~c16_pal; -// tv15hkz has quarter the pixel rate, so we need a 7mhz clock for the OSD -reg clk7; -reg clk14; - -always @(posedge clk28) begin - - reg [1:0] counter; - - counter <= counter + 1'd1; - clk7 <= !counter; - clk14 <= !counter[0]; -end - // A PLL to derive the system clock from the MiSTs 27MHz wire pll_c1541_locked, clk32; pll_c1541 pll_c1541 ( diff --git a/cores/c16/data_io.v b/cores/c16/data_io.v deleted file mode 100644 index a2439d0..0000000 --- a/cores/c16/data_io.v +++ /dev/null @@ -1,127 +0,0 @@ -// -// data_io.v -// -// io controller writable ram 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 . -// - -module data_io ( - // io controller spi interface - input sck, - input ss, - input sdi, - - output downloading, // signal indicating an active download - output [15:0] size, // number of bytes in input buffer - output reg [7:0] index, // menu index used to upload the file - - // external ram interface - input clk, - output reg wr, - output reg [15:0] a, - output [7:0] d -); - -assign d = data; - -parameter START_ADDR = 16'h0000; - -assign size = addr; - -// ********************************************************************************* -// spi client -// ********************************************************************************* - -// this core supports only the display related OSD commands -// of the minimig -reg [6:0] sbuf; -reg [7:0] cmd /* synthesis noprune */; -reg [7:0] data /* synthesis noprune */; -reg [4:0] cnt /* synthesis noprune */; - -reg [15:0] addr /* synthesis noprune */; -reg rclk /* synthesis noprune */; - -localparam UIO_FILE_TX = 8'h53; -localparam UIO_FILE_TX_DAT = 8'h54; -localparam UIO_FILE_INDEX = 8'h55; -localparam UIO_FILE_INFO = 8'h56; - -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 <= addr + 16'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 <= START_ADDR; - 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; - a <= addr; - end - - // expose file (menu) index - if((cmd == UIO_FILE_INDEX) && (cnt == 15)) - index <= {sbuf[6: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 \ No newline at end of file diff --git a/cores/c16/osd.v b/cores/c16/osd.v deleted file mode 100644 index 9151d26..0000000 --- a/cores/c16/osd.v +++ /dev/null @@ -1,208 +0,0 @@ -// -// osd.v -// -// A simple OSD implementation. Can be hooked up between a cores -// VGA output and the physical VGA pins -// -// Sinclair QL for the MiST -// https://github.com/mist-devel -// -// 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 osd ( - // OSDs pixel clock, should be synchronous to cores pixel clock to - // avoid jitter. - input clk_sys, - input ce_pix, - - // SPI interface - input sck, - input ss, - input sdi, - - // VGA signals coming from core - input [5:0] red_in, - input [5:0] green_in, - input [5:0] blue_in, - input hs_in, - input vs_in, - - // VGA signals going to video connector - output [5:0] red_out, - output [5:0] green_out, - output [5:0] blue_out, - output hs_out, - output vs_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 [7:0] sbuf; -reg [7:0] cmd; -reg [4:0] cnt; -reg [10:0] bcnt; -reg osd_enable; - -reg [7:0] osd_buffer [2047:0]; // the OSD buffer itself - -// the OSD has its own SPI interface to the io controller -always@(posedge sck, posedge ss) begin - if(ss == 1'b1) begin - cnt <= 5'd0; - bcnt <= 11'd0; - end else begin - sbuf <= { sbuf[6:0], sdi}; - - // 0:7 is command, rest payload - if(cnt < 15) - cnt <= cnt + 4'd1; - else - cnt <= 4'd8; - - if(cnt == 7) begin - cmd <= {sbuf[6:0], sdi}; - - // lower three command bits are line address - bcnt <= { sbuf[1:0], sdi, 8'h00}; - - // command 0x40: OSDCMDENABLE, OSDCMDDISABLE - if(sbuf[6:3] == 4'b0100) - osd_enable <= sdi; - end - - // command 0x20: OSDCMDWRITE - if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin - osd_buffer[bcnt] <= {sbuf[6:0], sdi}; - bcnt <= bcnt + 11'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] h_dsp_width = hs_pol?hs_low:hs_high; -wire [9:0] h_dsp_ctr = { 1'b0, h_dsp_width[9:1] }; - -always @(posedge clk_sys) begin - reg hsD; - - if (ce_pix) begin - hsD <= hs_in; - - // falling edge of hs_in - if(!hs_in && hsD) begin - h_cnt <= 10'd0; - hs_high <= h_cnt; - end - - // rising edge of hs_in - else if(hs_in && !hsD) begin - h_cnt <= 10'd0; - hs_low <= h_cnt; - end - - else - h_cnt <= h_cnt + 10'd1; - end -end - -// vertical counter -reg [9:0] v_cnt; -reg [9:0] vs_low, vs_high; -wire vs_pol = vs_high < vs_low; -wire [9:0] v_dsp_height = vs_pol?vs_low:vs_high; -wire [9:0] v_dsp_ctr = { 1'b0, v_dsp_height[9:1] }; -wire doublescan = (v_dsp_height>350); - -always @(posedge clk_sys) begin - reg hsD, vsD; - - hsD <= hs_in; - - if (~hsD & hs_in) begin - vsD <= vs_in; - - // falling edge of vs_in - if(!vs_in && vsD) begin - v_cnt <= 10'd0; - vs_high <= v_cnt; - end - - // rising edge of vs_in - else if(vs_in && !vsD) begin - v_cnt <= 10'd0; - vs_low <= v_cnt; - end - - else - v_cnt <= v_cnt + 10'd1; - end -end - -// area in which OSD is being displayed -wire [9:0] h_osd_start = h_dsp_ctr + OSD_X_OFFSET - (OSD_WIDTH >> 1); -wire [9:0] h_osd_end = h_dsp_ctr + OSD_X_OFFSET + (OSD_WIDTH >> 1) - 1'd1; -wire [9:0] v_osd_start = v_dsp_ctr + OSD_Y_OFFSET - (doublescan ? OSD_HEIGHT : OSD_HEIGHT >> 1); -wire [9:0] v_osd_end = v_dsp_ctr + OSD_Y_OFFSET + (doublescan ? OSD_HEIGHT : OSD_HEIGHT >> 1) - 1'd1; - -reg h_osd_active, v_osd_active; -always @(posedge clk_sys) begin - if(hs_in != hs_pol) begin - if(h_cnt == h_osd_start) h_osd_active <= 1'b1; - if(h_cnt == h_osd_end) h_osd_active <= 1'b0; - end - if(vs_in != vs_pol) begin - if(v_cnt == v_osd_start) v_osd_active <= 1'b1; - if(v_cnt == v_osd_end) v_osd_active <= 1'b0; - end -end - -wire osd_de = osd_enable && h_osd_active && v_osd_active; - -wire [9:0] osd_hcnt = h_cnt - h_osd_start + 7'd1; // one pixel offset for osd_byte register -wire [9:0] osd_vcnt = v_cnt - v_osd_start; - -reg [7:0] osd_byte; -always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}]; -wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]]; - -wire [2:0] osd_color = OSD_COLOR; -assign red_out = !osd_de?red_in: {osd_pixel, osd_pixel, osd_color[2], red_in[5:3] }; -assign green_out = !osd_de?green_in:{osd_pixel, osd_pixel, osd_color[1], green_in[5:3]}; -assign blue_out = !osd_de?blue_in: {osd_pixel, osd_pixel, osd_color[0], blue_in[5:3] }; - -assign hs_out = hs_in; -assign vs_out = vs_in; - -endmodule diff --git a/cores/c16/rgb2ypbpr.sv b/cores/c16/rgb2ypbpr.sv deleted file mode 100644 index 1e1662e..0000000 --- a/cores/c16/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/c16/scandoubler.v b/cores/c16/scandoubler.v deleted file mode 100644 index 9915fd2..0000000 --- a/cores/c16/scandoubler.v +++ /dev/null @@ -1,177 +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, - - // shifter video interface - input hs_in, - input vs_in, - input [3:0] r_in, - input [3:0] g_in, - input [3: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 -); - - -// try to detect changes in input signal and lock input clock gate -// it -reg last_hs_in; -reg [1:0] i_div; -wire ce_x1 = (i_div == 2'b01); -wire ce_x2 = i_div[0]; - -always @(posedge clk_sys) begin - if(last_hs_in != hs_in) begin - i_div <= 2'b00; - last_hs_in <= hs_in; - 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; -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 <= { sd_out[11:8], 2'b00 }; - g_out <= { sd_out[7:4], 2'b00 }; - b_out <= { sd_out[3:0], 2'b00 }; - end else begin - case(scanlines) - 1: begin // reduce 25% = 1/2 + 1/4 - r_out <= {1'b0, sd_out[11:8], 1'b0} + {2'b00, sd_out[11:8]}; - g_out <= {1'b0, sd_out[7:4], 1'b0} + {2'b00, sd_out[7:4] }; - b_out <= {1'b0, sd_out[3:0], 1'b0} + {2'b00, sd_out[3:0] }; - end - - 2: begin // reduce 50% = 1/2 - r_out <= {1'b0, sd_out[11:8], 1'b0}; - g_out <= {1'b0, sd_out[7:4], 1'b0}; - b_out <= {1'b0, sd_out[3:0], 1'b0}; - end - - 3: begin // reduce 75% = 1/4 - r_out <= {2'b00, sd_out[11:8]}; - g_out <= {2'b00, sd_out[7:4]}; - b_out <= {2'b00, sd_out[3:0]}; - end - endcase - end - end -end - -// scan doubler output register -reg [11:0] sd_out; - -// ================================================================== -// ======================== the line buffers ======================== -// ================================================================== - -// 2 lines of 512 pixels 3*4 bit RGB -(* ramstyle = "no_rw_check" *) reg [11:0] sd_buffer[1023:0]; - -// use alternating sd_buffers when storing/reading data -reg line_toggle; - -// total hsync time (in 16MHz cycles), hs_total reaches 1024 -reg [8:0] hs_max; -reg [8:0] hs_rise; -reg [8: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 <= 9'd0; - end else begin - hcnt <= hcnt + 9'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 [8: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 + 9'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/c16/stp1.stp b/cores/c16/stp1.stp deleted file mode 100644 index 1183210..0000000 --- a/cores/c16/stp1.stp +++ /dev/null @@ -1,1186 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 'C16:c16|kernal_dl_write' == rising edge - - - - - - - 111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000011111111111111111111111101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000 - 111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000011111111111111111111111101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000 - - - - - - - - - - - - - - - - - - - 11111111101111111111000000001111111111111100111111010111111011111111110100001111110111111110011111111100111111011111111110111111111100000000111111111111110011111101011111101111111111010000111111111111111001111111110011111101111111111011111111110000000011111111111111001111110101111110111111111101000011111100001111100111111111001111110111111111101111111111000000001111111111111100111111010111111011111111110100001111111000111110011111111100111111011100000011111111111100000000111111111111110011111101100101110000001011010000111111010011111001111111110011111101110000001111111111110000000011111111111111001111110110010111000000101101000011111111001111100111111111001111110111000000111111111111000000001111111111111100111111011001011100000010110100001111110010111110011111111100111111011100000011111111111100000000111111111111110011111101100101110000001011010000111111101011111001111111110011111101110000001111111111110000000011111111111111001111110110010111000000101101000011111101101111100111111111001111110111000000101111111111000000001111111111111100111111011001011100000010110100001111111110111110011111111100111111011000101110111111111100000000111111111111110011111101100101110000001011010000111111000111111001111111110011111101100010111011111111110000000011111111111111001111110110010111000000101101000011111110011111100111111111001111110110001011101111111111000000001111111111111100111111011001011100000010110100001111110101111110011111111100111111011000101110111111111100000000111111111111110011111101100101110000001011010000111111110111111001111111110011111101100010111011111111110000000011111111111111001111110110010111000000101101000011111100110000000000000000000001110110001011101111111111000000001111111111111100111111011001011100000010110100001111111011000000000000000000000111011000101110111111111100000000000000000000000000011111100101110000001011010000111111011100000000000000000000011111100010111011111111110000000000000000000000000001110110010111000000101101000011111111110000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100001111110000000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000111111100000000000000000000000011101001111111111111111110000000000000000000000000001110101111110111111111101000011111101000000000000000000000001110100111111111111111111000000000000000000000000000111010111111011111111110100001111111100000000000000000000000111010011111111111111111100000000000000000000000000011101011111101111111111010000111111001000000000000000000000011101001111111111111111110000000000000000000000000001110101111110111111111101000011111110100000000000000000000001110100111111111111111111000000000000000000000000000111010111111011111111110100001111110110000000000000000000000111010011111110111111111100000000000000000000000000011101011111101111111111010000111111111000000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000011111100010000000000000000000001110111111111101111111111000000000000000000000000000111010111111011111111110100000001111001000000000000000000000111011111111110111111111100000000000000000000000000011101011111101111111111010000000111010100000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000000011111010000000000000000000001110111111111101111111111000000000000000000000000000111010111111011111111110100000001110011000000000000000000000111011111111110111111111100000000000000000000000000011101011111101111111111010000000111101100000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000000011101110000000000000000000001110111111111101111111111000000000000000000000000000111010111111011111111110100000001111111000000000000000000000111011111111110111111111100000000000000000000000000011101011111101111111111010000000111000000000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000000011110000000000000000000000001110111000000111111111111000000000000000000000000000111011001011100000010110100000001110100000000000000000000000111011100000011111111111100000000000000000000000000011101100101110000001011010000000111110000000000000000000000011101110000001111111111110000000000000000000000000001110110010111000000101101000000011100100000000000000000000001110111000000111111111111000000000000000000000000000111011001011100000010110100000001111010000000000000000000000111011100000011111111111100000000000000000000000000011101100101110000001011010000000111011000000000000000000000011101110000001011111111110000000000000000000000000001110110010111000000101101000000011111100000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001110001000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000000111100100000000000000000000011101100010111011111111110000000000000000000000000001110110010111000000101101000000011101010000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001111101000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000000111001100000000000000000000011101100010111011111111110000000000000000000000000001110110010111000000101101000000011110110000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001110111000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000000111111100000000000000000000011101100010111011111111110000000000000000000000000001110110010111000000101101000000011100000000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001111000000000000000000000000111010011111111111111111100000000000000000000000000011101011111101111111111010000000111010010000000000000000100000001001111111111111111110000000000000000000000000001110101111110111111111101000000011111001000000000000000010000000100111111111111111111000000001000000000000001000000110111111011111111110100000001110010100000000000000001000000110011111111111111111100000000100000000000000100000001011111101111111111010000000111101010000000000000000100000001001111111111111111110000000010000000000000010000000101111110111111111101000000011101101000000000000000010000000100111111101111111111000000001000000000000001000000010111111011111111110100000001111110100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010000000111000110000000000000000100000001111111111011111111110000000010000000000000010000000101111110111111111101000100000010011000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000000101100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010001000000110110000000000000000100000001111111111011111111110000000010000000000000010000000101111110111111111101000100000000111000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000001011100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010001000000011110000000000000000100000001111111111011111111110000000010000000000000010000000101111110111111111101000100000011111000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000000000100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010001000000100010000000000000000100000001110000001111111111110000000010000000000000010000000110010111000000101101000100000001001000000000000000010000000111000000111111111111000000001000000000000001000000011001011100000010110100010000001100100000000000000001000000011100000011111111111100000000100000000000000100000001100101110000001011010001000000001010000000000000000100000001110000001111111111110000000010000000000000010000000110010111000000101101000100000010101000000000000000010000000111000000111111111111000000001000000000000001000000011001011100000010110100010000000110100000000000000001000000011100000010111111111100000000100000000000000100000001100101110000001011010001000000111010000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000000011000000000000000010000000110001011101111111111000000001000000000000001000000011001011100000010110100010000001001100000000000000001000000011000101110111111111100000000100000000000000100000001100101110000001011010001000000010110000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000011011000000000000000010000000110001011101111111111000000001000000000000001000000011001011100000010110100010000000011100000000000000001000000011000101110111111111100000000100000000000000100000001100101110000001011010001000000101110000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000001111000000000000000010000000110001011101111111111000000001000000000000001000000011001011100000010110100010000001111100000000000000001000000011000101110111111111100000000100000000000000100000001100101110000001011010001000000000010000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000010001000000000000000010000000100111111111111111111000000001000000000000001000000010111111011111111110100010000000100100000000000000001000000010011111111111111111100000000100000000000000100000001011111101111111111010001000000110010000000000000000100000001001111111111111111110000000010000000000000010000000101111110111111111101000100000000101000000000000000010000000100111111111111111111000000001000000000000001000000010111111011111111110100010000001010100000000000000001000000010011111111111111111100000000100000000000000100000001011111101111111111010001000000011010000000000000000100000001001111111011111111110000000010000000000000010000000101111110111111111101000100000011101000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000000001000000010000000000001001011111111110111111111100000000100000000000000100000001011111101111111111010001000000100100000001000000000000100101111111111011111111110000000000000100000000000010011101111110111111111101000100000001010000000100000000000010011111111111101111111111000000000000010000000000001001010111111011111111110100010000001101000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010001000000001100000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000100000010110000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100010000000111000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010001000000111100000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000100000000000000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100010000001000000000010000000000001001011100000011111111111100000000000001000000000000100101100101110000001011010001000000010000000001000000000000100101110000001111111111110000000000000100000000000010010110010111000000101101000100000011000000000100000000000010010111000000111111111111000000000000010000000000001001011001011100000010110100010000000010000000010000000000001001011100000011111111111100000000000001000000000000100101100101110000001011010001000000101000000001000000000000100101110000001111111111110000000000000100000000000010010110010111000000101101000100000001100000000100000000000010010111000000101111111111000000000000010000000000001001011001011100000010110100010000001110000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010001000000000100000001000000000000100101100010111011111111110000000000000100000000000010010110010111000000101101000000100110010000000100000000000010010110001011101111111111000000000000010000000000001001011001011100000010110100000010010101000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010000001001110100000001000000000000100101100010111011111111110000000000000100000000000010010110010111000000101101000000100100110000000100000000000010010110001011101111111111000000000000010000000000001001011001011100000010110100000010011011000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010000001001011100000001000000000000100101100010111011111111110000000000000100000000000010010110010111000000101101000000100111110000000100000000000010010110001011101111111111000000000000010000000000001001011001011100000010110100000010010000000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010000001001100000000001000000000000100101001111111111111111110000000000000100000000000010010101111110111111111101000000100101000000000100000000000010010100111111111111111111000000000000010000000000001001010111111011111111110100000010011100000000010000000000001001010011111111111111111100000000000001000000000000100101011111101111111111010000001001001000000001000000000000100101001111111111111111110000000000000100000000000010010101111110111111111101000000100110100000000100000000000010010100111111111111111111000000000000010000000000001001010111111011111111110100000010010110000000010000000000001001010011111110111111111100000000000001000000000000100101011111101111111111010000001001111000000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000000100100010000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100000010011001000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010000001001010100000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000000100111010000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100000010010011000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010000001001101100000001000000000000100101 - 1111111111111111T111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 - - - - - - - - - - - - - - - - - - diff --git a/cores/c16/user_io.v b/cores/c16/user_io.v deleted file mode 100644 index 999c474..0000000 --- a/cores/c16/user_io.v +++ /dev/null @@ -1,522 +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 emulation - output ps2_kbd_clk, - output reg ps2_kbd_data, - output ps2_mouse_clk, - output reg ps2_mouse_data, - - // 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 - - //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; - - 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; - 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; - 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 [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 - - if(sd_din_strobe) begin - sd_din_strobe<= 0; - if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; - 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; - - // fetch first byte when sectore FPGA->IO command has been seen - if(spi_byte_in == 8'h18) - sd_din_strobe <= 1'b1; - - 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: sd_din_strobe <= 1'b1; - - // 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 diff --git a/mist-modules b/mist-modules new file mode 160000 index 0000000..232c10f --- /dev/null +++ b/mist-modules @@ -0,0 +1 @@ +Subproject commit 232c10f768f2af8a7ed0f9b295727b2867cc6084