From c2d7c6627a100148335497ce238c87bf14947258 Mon Sep 17 00:00:00 2001 From: slederer Date: Thu, 13 Mar 2025 22:37:56 +0100 Subject: [PATCH 1/2] tridoracpu: reduce clock speed, fix vblank flag in vgafb --- .../tridoracpu.srcs/Arty-A7-35-Master.xdc | 2 + tridoracpu/tridoracpu.srcs/cpuclk.v | 4 +- .../tridoracpu.srcs/mig_dram_0/mig_a.prj | 6 +- .../tridoracpu.srcs/mig_dram_0/mig_b.prj | 6 +- tridoracpu/tridoracpu.srcs/top.v | 3 +- tridoracpu/tridoracpu.srcs/vgafb.v | 8 +- tridoracpu/tridoracpu.xpr | 94 ++++++++++++------- 7 files changed, 76 insertions(+), 47 deletions(-) diff --git a/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc b/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc index c618478..7c62767 100644 --- a/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc +++ b/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc @@ -216,3 +216,5 @@ set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports rst] #set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_p }]; #IO_L8P_T1_AD10P_15 Sch=ad_p[10] set_property BITSTREAM.GENERAL.COMPRESS True [current_design] + +set_max_delay -from [get_pins vgafb0/display_timings_inst/o_vblank_reg/C] -to [get_pins vgafb0/vblank_xfer_reg/D] 3.000 diff --git a/tridoracpu/tridoracpu.srcs/cpuclk.v b/tridoracpu/tridoracpu.srcs/cpuclk.v index 613d85e..a214cc4 100644 --- a/tridoracpu/tridoracpu.srcs/cpuclk.v +++ b/tridoracpu/tridoracpu.srcs/cpuclk.v @@ -17,7 +17,9 @@ module cpu_clkgen( .CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB (-360.000-360.000). .CLKIN1_PERIOD(10.0), // Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz). // CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128) - .CLKOUT0_DIVIDE_F(12.0), // Divide amount for CLKOUT0 (1.000-128.000). + // CPU Clock: 12.0 = 83.33MHz CPU Clock, 333.33MHz Memory Clock + // 13.0 = 76.92MHz CPU Clock, 307.69MHz Memory Clock + .CLKOUT0_DIVIDE_F(13.0), // Divide amount for CLKOUT0 (1.000-128.000). .CLKOUT1_DIVIDE(5), .CLKOUT2_DIVIDE(40), // 40 = 25MHz pixel clock (should be 25.175MHz per spec) for 640x480 //.CLKOUT2_DIVIDE(25), // 25 = 40MHz pixel clock for 800x600 diff --git a/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_a.prj b/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_a.prj index b263a25..58ff963 100644 --- a/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_a.prj +++ b/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_a.prj @@ -39,12 +39,12 @@ DDR3_SDRAM/Components/MT41K128M16XX-15E - 3000 + 3300 1.8V 4:1 - 83.333 + 75.757 0 - 666 + 606 1.000 1 1 diff --git a/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_b.prj b/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_b.prj index b263a25..99d2e0c 100644 --- a/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_b.prj +++ b/tridoracpu/tridoracpu.srcs/mig_dram_0/mig_b.prj @@ -39,12 +39,12 @@ DDR3_SDRAM/Components/MT41K128M16XX-15E - 3000 + 3250 1.8V 4:1 - 83.333 + 76.923 0 - 666 + 615 1.000 1 1 diff --git a/tridoracpu/tridoracpu.srcs/top.v b/tridoracpu/tridoracpu.srcs/top.v index e79d611..2af2d10 100644 --- a/tridoracpu/tridoracpu.srcs/top.v +++ b/tridoracpu/tridoracpu.srcs/top.v @@ -3,7 +3,8 @@ // or as clk_1hz for debugging `define clock cpuclk -`define clkfreq 83333333 +//`define clkfreq 83333333 +`define clkfreq 76923076 //`define clock clk //`define clkfreq 100000000 //`define clock clk_1hz diff --git a/tridoracpu/tridoracpu.srcs/vgafb.v b/tridoracpu/tridoracpu.srcs/vgafb.v index 4e8d668..37c1376 100644 --- a/tridoracpu/tridoracpu.srcs/vgafb.v +++ b/tridoracpu/tridoracpu.srcs/vgafb.v @@ -62,10 +62,11 @@ module display_timings #( // o_scanline: high for one tick at the start of each visible scanline assign o_scanline = (o_sy >= VA_STA) && (o_sy <= VA_END) && (o_sx == H_STA); + // set vblank at end of frame, clear at start always @(posedge i_pix_clk) begin - if(o_frame) o_vblank <= 1; - else if (o_de) o_vblank <= 0; + if(o_sy == VA_END) o_vblank <= 1; + else if (o_sy == -1) o_vblank <= 0; end always @ (posedge i_pix_clk) @@ -175,6 +176,7 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) ( wire scanline; // scanline start wire vblank; // vertical blank reg vblank_buf; // vertical blank in cpu clock domain + reg vblank_xfer; // vertical blank clock domain crossing display_timings #( // 640x480 800x600 1280x720 1920x1080 `ifdef RES_1024_768 @@ -233,7 +235,7 @@ module vgafb #(VMEM_ADDR_WIDTH = 15, VMEM_DATA_WIDTH = 32) ( always @(posedge pix_clk) frame_d <= frame; - always @(posedge cpu_clk) vblank_buf <= vblank; + always @(posedge cpu_clk) { vblank_buf, vblank_xfer } <= { vblank_xfer, vblank }; always @(posedge cpu_clk) begin diff --git a/tridoracpu/tridoracpu.xpr b/tridoracpu/tridoracpu.xpr index a4c6545..721335b 100644 --- a/tridoracpu/tridoracpu.xpr +++ b/tridoracpu/tridoracpu.xpr @@ -1,9 +1,10 @@ - - - + + + + - + - + @@ -233,18 +255,6 @@ - - - - - - - - - - @@ -298,6 +308,18 @@ + + + + + + + + + + @@ -317,8 +339,8 @@ - - + + @@ -328,17 +350,17 @@ - + - + - + - + @@ -364,9 +386,9 @@ - + - + @@ -377,7 +399,7 @@ - + From 3f40c50170fec9cbb2e3b7d0a4720f869db9200f Mon Sep 17 00:00:00 2001 From: slederer Date: Thu, 13 Mar 2025 23:15:45 +0100 Subject: [PATCH 2/2] lib: prepare rommon and corelib for different clock speeds --- lib/corelib.s | 16 +++++++++++----- lib/rommon.s | 22 +++++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/corelib.s b/lib/corelib.s index 57f35a8..6970971 100644 --- a/lib/corelib.s +++ b/lib/corelib.s @@ -588,13 +588,19 @@ DIVU_END: ; wait approx. 1 millisecond ; -; 83.333 MHz Clock, three instructions a 4 cycles -; 83333 / 12 = 6944.4166 -; works only if executed without wait states (i.e. -; from BRAM/SRAM) +; the ROM at address 4 +; contains the cpu clock freq in KHz + .EQU CLK_KHZ_ADDR 4 WAIT1MSEC: - LOADCP 6944 + LOADC CLK_KHZ_ADDR + LOADI + ; divide by 16 + SHR + SHR + SHR + SHR WAIT1LOOP: + INC 0 ; NOP to make the loop 16 cycles long DEC 1 DUP CBRANCH.NZ WAIT1LOOP diff --git a/lib/rommon.s b/lib/rommon.s index a967e4b..4828008 100644 --- a/lib/rommon.s +++ b/lib/rommon.s @@ -7,8 +7,16 @@ .EQU UART_REG 2048 .EQU MON_ADDR 64512 + .EQU CLK_KHZ 76923 + BRANCH 2 ; the very first instruction is not ; executed correctly + BRANCH MON_START ; branch over constant + +CLK_KHZ_ADDR: + .WORD CLK_KHZ ; to calibrate the delay loop + +MON_START: LOADCP 65020 ; initialise FP and RP registers STOREREG FP LOADCP 65024 @@ -782,13 +790,17 @@ COPY_BLK1: ; wait approx. 1 millisecond ; -; 83.333 MHz Clock, three instructions a 4 cycles -; 83333 / 12 = 6944.4166 -; works only if executed without wait states (i.e. -; from BRAM/SRAM) WAIT1MSEC: - LOADCP 6944 + ; get clock freq in khz + LOADC CLK_KHZ_ADDR + LOADI + ; divide by 16 + SHR + SHR + SHR + SHR WAIT1LOOP: + INC 0 ; NOP to make loop 16 cycles long DEC 1 DUP CBRANCH.NZ WAIT1LOOP