From d9ea753effa220fc388c7d9da84e7a09268360b8 Mon Sep 17 00:00:00 2001 From: Eugene Lozovoy Date: Mon, 17 Apr 2023 12:19:19 +0300 Subject: [PATCH] initial add source files --- Makefile | 29 ++++++++ clocks.sdc | 2 + scandoubler.qpf | 30 +++++++++ scandoubler.qsf | 143 ++++++++++++++++++++++++++++++++++++++++ scandoubler.v | 123 ++++++++++++++++++++++++++++++++++ testbench_scandoubler.v | 101 ++++++++++++++++++++++++++++ 6 files changed, 428 insertions(+) create mode 100644 Makefile create mode 100644 clocks.sdc create mode 100644 scandoubler.qpf create mode 100644 scandoubler.qsf create mode 100644 scandoubler.v create mode 100644 testbench_scandoubler.v diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..caefaa9 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +export PATH:=/opt/quartus13.0sp1/quartus/bin:/cygdrive/c/Hwdev/quartus130sp1/quartus/bin:/opt/modelsim201/modelsim_ase/bin:/cygdrive/c/Hwdev/modelsim181/modelsim_ase/win32aloem:${PATH} + +.PHONY: build program report testbench clean + +build: + quartus_sh --no_banner --flow compile scandoubler -c scandoubler + +program: + quartus_pgm --no_banner --mode=jtag -o "BVP;output_files/scandoubler.pof" + +report: + cat output_files/scandoubler.*.smsg output_files/scandoubler.*.rpt |grep -e Error -e Critical -e Warning |grep -v -e "Family doesn't support jitter analysis" -e "Force Fitter to Avoid Periphery Placement Warnings" + +testbench: testbench_scandoubler + +testbench_scandoubler: V=$@.v scandoubler.v + +testbench_%: + test ! -d work || rm -rf work + vlib work + test ! -n "$(filter %.v,${V})" || vlog -quiet -sv $(filter %.v,${V}) + test ! -n "$(filter %.vhd %.vhdl,${V})" || vcom -quiet $(filter %.vhd %.vhdl,${V}) + vsim ${VSIMFLAGS} -batch -quiet -do 'run -all' $@ + test ! -r transcript || rm transcript + +clean: + rm -rf db/ incremental_db/ output_files/ ivl_vhdl_work/ work/ *.bin *.mem *.vcd + +-include Makefile.local diff --git a/clocks.sdc b/clocks.sdc new file mode 100644 index 0000000..3a89bc1 --- /dev/null +++ b/clocks.sdc @@ -0,0 +1,2 @@ +create_clock -name F14 -period 14.1MHz [get_ports {F14}] +create_generated_clock -name F14_2 -source [get_ports {F14}] -phase 45 [get_ports {F14_2}] diff --git a/scandoubler.qpf b/scandoubler.qpf new file mode 100644 index 0000000..cef47c1 --- /dev/null +++ b/scandoubler.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.0 Build 132 02/25/2009 SJ Web Edition +# Date created = 11:17:07 July 22, 2009 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "9.0" +DATE = "11:17:07 July 22, 2009" + +# Revisions + +PROJECT_REVISION = "scandoubler" diff --git a/scandoubler.qsf b/scandoubler.qsf new file mode 100644 index 0000000..2c2c6e5 --- /dev/null +++ b/scandoubler.qsf @@ -0,0 +1,143 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.0 Build 132 02/25/2009 SJ Web Edition +# Date created = 11:17:07 July 22, 2009 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# VGA_PAL_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + +set_global_assignment -name FAMILY MAX3000A +set_global_assignment -name DEVICE "EPM3128ATC100-10" +set_global_assignment -name TOP_LEVEL_ENTITY scandoubler +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 9.0 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "11:17:07 JULY 22, 2009" +set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1" +set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga +set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP" +set_global_assignment -name SMART_RECOMPILE ON +set_global_assignment -name MAX7000_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_location_assignment PIN_1 -to B_IN +set_location_assignment PIN_2 -to G_IN +set_location_assignment PIN_5 -to R_IN +set_location_assignment PIN_6 -to B_VIDEO +set_location_assignment PIN_8 -to G_VIDEO +set_location_assignment PIN_10 -to R_VIDEO +set_location_assignment PIN_13 -to A[10] +set_location_assignment PIN_14 -to A[11] +set_location_assignment PIN_16 -to A[12] +set_location_assignment PIN_17 -to A[13] +set_location_assignment PIN_19 -to A[14] +set_location_assignment PIN_20 -to D[8] +set_location_assignment PIN_21 -to D[9] +set_location_assignment PIN_22 -to D[10] +set_location_assignment PIN_23 -to D[11] +set_location_assignment PIN_24 -to A[9] +set_location_assignment PIN_25 -to A[8] +set_location_assignment PIN_27 -to A[7] +set_location_assignment PIN_28 -to A[6] +set_location_assignment PIN_29 -to A[5] +set_location_assignment PIN_30 -to WE +set_location_assignment PIN_31 -to D[7] +set_location_assignment PIN_32 -to D[6] +set_location_assignment PIN_35 -to D[5] +set_location_assignment PIN_36 -to D[4] +set_location_assignment PIN_37 -to D[3] +set_location_assignment PIN_40 -to D[2] +set_location_assignment PIN_41 -to D[1] +set_location_assignment PIN_42 -to D[0] +set_location_assignment PIN_44 -to A[4] +set_location_assignment PIN_45 -to A[3] +set_location_assignment PIN_46 -to A[2] +set_location_assignment PIN_47 -to A[1] +set_location_assignment PIN_48 -to A[0] +set_location_assignment PIN_49 -to D[12] +set_location_assignment PIN_50 -to D[13] +set_location_assignment PIN_52 -to D[14] +set_location_assignment PIN_54 -to D[15] +set_location_assignment PIN_55 -to LB +set_location_assignment PIN_56 -to UB +set_location_assignment PIN_57 -to OE +set_location_assignment PIN_58 -to A[15] +set_location_assignment PIN_60 -to A[16] +set_location_assignment PIN_61 -to A17 +set_location_assignment PIN_64 -to R_VGA +set_location_assignment PIN_68 -to G_VGA +set_location_assignment PIN_70 -to B_VGA +set_location_assignment PIN_71 -to VSYNC_VGA +set_location_assignment PIN_72 -to HSYNC_VGA +set_location_assignment PIN_83 -to SYNC_VIDEO +set_location_assignment PIN_84 -to SET_FK_OUT +set_location_assignment PIN_85 -to SET_FK_IN +set_location_assignment PIN_92 -to VGA_SCART +set_location_assignment PIN_93 -to INVERSE_F14MHZ +set_location_assignment PIN_94 -to INVERSE_SSI +set_location_assignment PIN_96 -to INVERSE_KSI +set_location_assignment PIN_97 -to INVERSE_RGBI +set_location_assignment PIN_98 -to SSI_IN +set_location_assignment PIN_99 -to KSI_IN +set_location_assignment PIN_100 -to I_IN +set_global_assignment -name STRATIXII_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name STRATIX_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name MAXII_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name APEX20K_OPTIMIZATION_TECHNIQUE AREA +set_location_assignment PIN_87 -to F14 +set_global_assignment -name RTLV_GROUP_RELATED_NODES OFF +set_global_assignment -name AUTO_PARALLEL_EXPANDERS OFF +set_global_assignment -name IGNORE_LCELL_BUFFERS ON +set_global_assignment -name IGNORE_CASCADE_BUFFERS ON +set_global_assignment -name MAX7000_FANIN_PER_CELL 50 +set_location_assignment PIN_7 -to I_VIDEO[2] +set_location_assignment PIN_9 -to I_VIDEO[1] +set_location_assignment PIN_12 -to I_VIDEO[0] +set_location_assignment PIN_63 -to I_VGA[0] +set_location_assignment PIN_67 -to I_VGA[1] +set_location_assignment PIN_69 -to I_VGA[2] +set_location_assignment PIN_81 -to F14_2 +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF +set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 +set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF +set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 +set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF +set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON +set_global_assignment -name FITTER_EFFORT "STANDARD FIT" +set_global_assignment -name TIMEQUEST_DO_REPORT_TIMING ON +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL OFF +set_global_assignment -name SAVE_DISK_SPACE OFF +set_global_assignment -name VERILOG_FILE scandoubler.v +set_global_assignment -name SDC_FILE clocks.sdc +set_global_assignment -name ALLOW_POWER_UP_DONT_CARE OFF diff --git a/scandoubler.v b/scandoubler.v new file mode 100644 index 0000000..db0aff0 --- /dev/null +++ b/scandoubler.v @@ -0,0 +1,123 @@ +module scandoubler( + input R_IN, + input G_IN, + input B_IN, + input I_IN, + + input KSI_IN, + input SSI_IN, + input F14, + input F14_2, + + input INVERSE_RGBI, + input INVERSE_KSI, + input INVERSE_SSI, + input INVERSE_F14MHZ, + input VGA_SCART, + input SET_FK_IN, + input SET_FK_OUT, + + output R_VGA, + output G_VGA, + output B_VGA, + output [2:0] I_VGA, + output VSYNC_VGA, + output HSYNC_VGA, + + output R_VIDEO, + output G_VIDEO, + output B_VIDEO, + output [2:0] I_VIDEO, + output SYNC_VIDEO, + + output A17, + output [16:0] A, + output WE, + output OE, + output UB, + output LB, + inout [15:0] D +); + + +reg ssi = 0, ksi0 = 0; +wire ksi = ksi0 ^ ~KSI_IN; +reg [6:0] ssi_cnt = 0; +always @(posedge F14) begin + if (SSI_IN == ksi0) begin + ssi_cnt <= ssi_cnt + 1'b1; + if (&ssi_cnt) + ksi0 <= ~ksi0; + ssi <= 1'b0; + end + else if (|ssi_cnt) begin + ssi_cnt <= 0; + ssi <= 1'b1; + end + else begin + ssi <= 1'b0; + end +end + +reg [10:0] hcnt = 0; +reg [10:0] hlen = 0; +reg even_line = 0; +always @(posedge F14) begin + if (ssi) begin + even_line = !even_line; + hlen <= hcnt; + hcnt <= 0; + end + else begin + hcnt <= hcnt + 1'b1; + end +end + +reg [9:0] hcnt_vga = 0; +always @(posedge F14) begin + if (hcnt_vga == hlen[10:1] || ssi) + hcnt_vga <= 0; + else + hcnt_vga <= hcnt_vga + 1'b1; +end + +assign VSYNC_VGA = ~INVERSE_KSI ^ ksi; +assign HSYNC_VGA = ~INVERSE_SSI ^ (hcnt_vga < 54); // ~3.85us + +assign OE = 1'b0; +assign A17 = 1'b0; +wire write_screen = F14 ^ INVERSE_F14MHZ & !ssi; +assign WE = ~write_screen; +assign UB = write_screen? ~hcnt[0] : 1'b0; +assign LB = write_screen? hcnt[0] : 1'b0; +assign A[16:0] = write_screen? + {{6{1'b0}}, ~even_line, hcnt[10:1]} : + {{6{1'b0}}, even_line, hcnt_vga} ; + +assign D[15:0] = write_screen? {{4{1'b0}}, I_IN, B_IN, G_IN, R_IN, {4{1'b0}}, I_IN, B_IN, G_IN, R_IN} : {16{1'bz}}; + +reg [3:0] ibgr_reg1, ibgr_reg2; +always @(posedge F14) begin + if (write_screen) begin + ibgr_reg1 <= D[3:0]; + ibgr_reg2 <= D[11:8]; + end +end + +assign R_VGA = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[0] : ibgr_reg1[0]); +assign G_VGA = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[1] : ibgr_reg1[1]); +assign B_VGA = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[2] : ibgr_reg1[2]); +assign I_VGA[0] = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[3] : ibgr_reg1[3]); +assign I_VGA[1] = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[3] : ibgr_reg1[3]); +assign I_VGA[2] = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[3] : ibgr_reg1[3]); + +assign R_VIDEO = R_IN ^ ~INVERSE_RGBI; +assign G_VIDEO = G_IN ^ ~INVERSE_RGBI; +assign B_VIDEO = B_IN ^ ~INVERSE_RGBI; +assign I_VIDEO[0] = I_IN ^ ~INVERSE_RGBI; +assign I_VIDEO[1] = I_IN ^ ~INVERSE_RGBI; +assign I_VIDEO[2] = I_IN ^ ~INVERSE_RGBI; +assign SYNC_VIDEO = ~((SSI_IN ^ ~INVERSE_SSI) ^ (KSI_IN ^ ~INVERSE_KSI)); + + +endmodule diff --git a/testbench_scandoubler.v b/testbench_scandoubler.v new file mode 100644 index 0000000..d43662e --- /dev/null +++ b/testbench_scandoubler.v @@ -0,0 +1,101 @@ +`timescale 1ns/100ps + +module testbench_scandoubler(); + +reg rst_n; +reg clk14 = 0; +wire clk14_2; +always #36 clk14 = ~clk14; +assign #18 clk14_2 = clk14; + +reg [8:0] vc = 0; +reg [9:0] hc0 = 0; +wire [8:0] hc = hc0[9:1]; +wire hc0_reset = hc0 == (448<<1) - 1'b1 ; +wire vc_reset = vc == 320 - 1'b1 ; +always @(posedge clk14) begin + if (hc0_reset) begin + hc0 <= 0; + if (vc_reset) + vc <= 0; + else + vc <= vc + 1'b1; + end + else begin + hc0 <= hc0 + 1'b1; + end +end + +wire hsync0 = hc[8:5] == 4'b1010; +wire vsync0 = vc[7:3] == 5'b11111; +reg csync; +always @(posedge clk14) if (hc[3]) begin + csync <= ~(vsync0 ^ hsync0); +end + +wire [15:0] d; +reg [15:0] ram [0:262143]; +reg [15:0] ram_q; +wire [15:0] ram_q0; +assign #10 ram_q0 = ram_q; +wire [17:0] ram_addr_a; +wire n_ramwr; +always @* begin + if (n_ramwr == 0) begin + ram[ram_addr_a] <= d; + end + ram_q <= ram[ram_addr_a]; +end +initial begin + integer i; + for (i = 0; i < 262143; i++) + ram[i] <= 16'h1234; +end +assign d = n_ramwr? ram_q0 : {16{1'bz}}; + +scandoubler scandoubler1( + .R_IN(1'b1), + .G_IN(1'b1), + .B_IN(1'b1), + .I_IN(1'b1), + .KSI_IN(1'b1), + .SSI_IN(csync), + .F14(clk14), + .F14_2(clk14_2), + .INVERSE_RGBI(1'b1), + .INVERSE_KSI(1'b1), + .INVERSE_SSI(1'b1), + .INVERSE_F14MHZ(1'b1), + .VGA_SCART(1'b1), + .SET_FK_IN(1'b1), + .SET_FK_OUT(1'b1), + .R_VGA(), + .G_VGA(), + .B_VGA(), + .I_VGA(), + .VSYNC_VGA(), + .HSYNC_VGA(), + .R_VIDEO(), + .G_VIDEO(), + .B_VIDEO(), + .I_VIDEO(), + .SYNC_VIDEO(), + .A17(ram_addr_a[17]), + .A(ram_addr_a[16:0]), + .WE(n_ramwr), + .OE(), + .UB(), + .LB(), + .D(d) +); + +initial begin + $dumpfile("testbench.vcd"); + $dumpvars(); + rst_n = 0; + #5 rst_n = 1; + #2100000 $finish; + #21000000 $finish; +end + +endmodule