From 993c3365072dcbbe8f25c9d6b1f87bb953b60f7b Mon Sep 17 00:00:00 2001 From: Eugene Lozovoy Date: Mon, 31 Oct 2022 21:49:02 +0300 Subject: [PATCH] improve compatibility with slower sram chips --- Makefile | 2 +- fpga/rtl/common.sv | 16 +++++------ fpga/rtl/cpucontrol.sv | 18 +++++++------ fpga/rtl/screen.sv | 60 +++++++++++++++++++++++------------------ fpga/rtl/top.sv | 36 ++++++++++++------------- fpga/syn/clocks.sdc | 17 +++++++----- fpga/syn/rev_A.qsf | 17 +++++++++--- fpga/syn/rev_B.qsf | 17 +++++++++--- fpga/syn/rev_zero_A.qsf | 19 +++++++------ 9 files changed, 118 insertions(+), 84 deletions(-) diff --git a/Makefile b/Makefile index bcd8415..e201c68 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ OUTDIR=out_new -REV=B +REV=zero_A .PHONY: all build_rev clean pipeline pipeline_sof diff --git a/fpga/rtl/common.sv b/fpga/rtl/common.sv index ec75b2c..2477216 100755 --- a/fpga/rtl/common.sv +++ b/fpga/rtl/common.sv @@ -6,14 +6,14 @@ endpackage interface cpu_bus(); - wire [15:0] a; - wire [7:0] d; - wire iorq; - wire mreq; - wire m1; - wire rfsh; - wire rd; - wire wr; + reg [15:0] a; + reg [7:0] d; + reg iorq; + reg mreq; + reg m1; + reg rfsh; + reg rd; + reg wr; reg [15:0] a_reg; reg [7:0] d_reg; diff --git a/fpga/rtl/cpucontrol.sv b/fpga/rtl/cpucontrol.sv index d207b21..58b8b16 100755 --- a/fpga/rtl/cpucontrol.sv +++ b/fpga/rtl/cpucontrol.sv @@ -16,7 +16,6 @@ module cpucontrol( input [2:0] rampage128, input machine_t machine, input turbo_t turbo, - input ext_wait_cycle, input init_done_in, output reg n_rstcpu, @@ -46,19 +45,22 @@ assign snow = bus.a[14] && ~bus.a[15] && bus.rfsh && (machine == MACHINE_S48 || /* CLOCK */ -reg [2:0] turbo_wait; -wire turbo_wait_trig0 = bus.rd || bus.wr; -reg turbo_wait_trig1; +reg [3:0] turbo_wait; +wire turbo_wait_trig0 = turbo == TURBO_14 && bus.mreq && !bus.rfsh; +wire turbo_wait_trig1 = turbo == TURBO_14 && (bus.rd || bus.wr); +reg turbo_wait_trig0_prev, turbo_wait_trig1_prev; always @(posedge clk28) begin - turbo_wait[0] <= turbo == TURBO_14 && turbo_wait_trig0 && !turbo_wait_trig1; - turbo_wait[1] <= turbo_wait[0] && (bus.iorq || ext_wait_cycle); + turbo_wait[0] <= turbo_wait_trig0 && !turbo_wait_trig0_prev; + turbo_wait[1] <= turbo_wait[0] || (turbo_wait_trig1 && !turbo_wait_trig1_prev); turbo_wait[2] <= turbo_wait[1]; - turbo_wait_trig1 <= turbo_wait_trig0; + turbo_wait[3] <= turbo_wait[2]; + turbo_wait_trig0_prev <= turbo_wait_trig0; + turbo_wait_trig1_prev <= turbo_wait_trig1; end reg clkcpu_prev; assign clkcpu_ck = clkcpu && !clkcpu_prev; -assign clkwait = contention || (|turbo_wait); +assign clkwait = contention || (|turbo_wait[3:1]); always @(posedge clk28) begin clkcpu_prev <= clkcpu; if (clkwait) diff --git a/fpga/rtl/screen.sv b/fpga/rtl/screen.sv index 7f4b508..23b9984 100755 --- a/fpga/rtl/screen.sv +++ b/fpga/rtl/screen.sv @@ -5,6 +5,7 @@ module screen( input clk28, input machine_t machine, + input turbo_t turbo, input [2:0] border, output reg [5:0] r, @@ -17,7 +18,7 @@ module screen( input fetch_allow, output reg fetch, output fetch_next, - output reg [14:0] addr, + output [14:0] addr, input [7:0] fetch_data, output contention, @@ -199,12 +200,16 @@ always @(posedge clk28 or negedge rst_n) begin end end -reg loading; +reg loading, loading_up; always @(posedge clk28 or negedge rst_n) begin - if (!rst_n) + if (!rst_n) begin loading <= 0; - else + loading_up <= 0; + end + else begin loading <= (vc < V_AREA) && (hc0 > 15) && (hc0 < (H_AREA<<2) + 17); + loading_up <= loading && (screen_update || loading_up); + end end @@ -213,19 +218,25 @@ wire [7:0] attr_border = {2'b00, border[2:0], border[2:0]}; reg [7:0] bitmap, attr, bitmap_next, attr_next; reg [7:0] up_ink0, up_paper0; -reg fetch_step; -wire fetch_bitmap = fetch && fetch_step == 1'd0; -wire fetch_attr = fetch && fetch_step == 1'd1; -assign fetch_next = loading && fetch_allow; +reg [1:0] fetch_cnt; +localparam FETCH_CYCLES = 2'd2; +assign fetch_next = loading && (fetch_allow || (|fetch_cnt && fetch_cnt != FETCH_CYCLES && turbo == TURBO_14)); -assign up_ink_addr = { attr_next[7:6], 1'b0, attr_next[2:0] }; -assign up_paper_addr = { attr_next[7:6], 1'b1, attr_next[5:3] }; +reg fetch_step; +wire fetch_bitmap = fetch && fetch_step == 1'd0 && fetch_cnt == FETCH_CYCLES; +wire fetch_attr = fetch && fetch_step == 1'd1 && fetch_cnt == FETCH_CYCLES; + +assign addr = (fetch_step == 1'd0)? + { 2'b10, vaddr[7:6], vaddr[2:0], vaddr[5:3], haddr[7:3] } : + { 5'b10110, vaddr[7:3], haddr[7:3] }; +assign up_ink_addr = loading_up? { attr_next[7:6], 1'b0, attr_next[2:0] } : { 3'b0, attr_border[2:0] }; +assign up_paper_addr = loading_up? { attr_next[7:6], 1'b1, attr_next[5:3] } : { 3'b0, attr_border[2:0] }; always @(posedge clk28 or negedge rst_n) begin if (!rst_n) begin - addr <= 0; fetch <= 0; fetch_step <= 0; + fetch_cnt <= 0; attr <= 0; bitmap <= 0; attr_next <= 0; @@ -234,23 +245,20 @@ always @(posedge clk28 or negedge rst_n) begin up_paper0 <= 0; end else begin - if (ck14) begin - addr <= ((fetch && fetch_step == 1'd1) || (!fetch && fetch_step == 1'b0))? - { 2'b10, vaddr[7:6], vaddr[2:0], vaddr[5:3], haddr[7:3] } : - { 5'b10110, vaddr[7:3], haddr[7:3] }; - - if (fetch) - fetch_step <= fetch_step + 1'b1; - fetch <= fetch_next; - - if (fetch_attr) + fetch <= fetch_next; + if (fetch_cnt == FETCH_CYCLES) begin + if (fetch_step == 1'd1) attr_next <= fetch_data; - else if (!loading) - attr_next <= attr_border; - if (fetch_bitmap) + if (fetch_step == 1'd0) bitmap_next <= fetch_data; - else if (!loading) - bitmap_next <= 0; + fetch_step <= fetch_step + 1'b1; + fetch_cnt <= 0; + end + else if (fetch && fetch_next && !next_addr) begin + fetch_cnt <= fetch_cnt + 1'b1; + end + else begin + fetch_cnt <= 0; end if (screen_show && screen_update) diff --git a/fpga/rtl/top.sv b/fpga/rtl/top.sv index 764c48b..d460f15 100755 --- a/fpga/rtl/top.sv +++ b/fpga/rtl/top.sv @@ -60,7 +60,6 @@ wire magic_reboot, magic_beeper; wire up_active; wire clkwait; wire [2:0] rampage128; -wire div_wait; wire init_done; wire screen_fetch, screen_fetch_next; @@ -74,8 +73,8 @@ always @(posedge clk28 or negedge rst_n) begin bus_memreq <= 0; end else if (!screen_fetch && !screen_fetch_next) begin - bus.a_reg <= bus.a; - bus.d_reg <= bus.d; + bus.a_reg <= {a[15:13], va[12:0]}; + bus.d_reg <= vd; bus_ioreq <= n_iorq == 1'b0 && n_m1 == 1'b1; bus_memreq <= n_mreq == 1'b0 && n_rfsh == 1'b1; end @@ -86,16 +85,18 @@ always @(posedge clk28 or negedge rst_n) begin bus_memreq <= 0; end end -assign bus.a = {a[15:13], va[12:0]}; -assign bus.d = vd; -assign bus.iorq = ~n_iorq; -assign bus.mreq = ~n_mreq; -assign bus.m1 = ~n_m1; -assign bus.rfsh = ~n_rfsh; -assign bus.rd = ~n_rd; -assign bus.wr = ~n_wr; -assign bus.ioreq = bus_ioreq & ~n_iorq; -assign bus.memreq = bus_memreq & ~n_mreq; +always @(posedge clk168) begin + bus.a <= {a[15:13], va[12:0]}; + bus.d <= vd; + bus.iorq <= ~n_iorq; + bus.mreq <= ~n_mreq; + bus.m1 <= ~n_m1; + bus.rfsh <= ~n_rfsh; + bus.rd <= ~n_rd; + bus.wr <= ~n_wr; +end +assign bus.ioreq = bus_ioreq & bus.iorq; +assign bus.memreq = bus_memreq & bus.mreq; /* RESET */ @@ -122,6 +123,7 @@ screen screen0( .clk28(clk28), .machine(machine), + .turbo(turbo), .border(screen_border), .r(r), @@ -131,7 +133,7 @@ screen screen0( .vsync(vsync), .hsync(hsync), - .fetch_allow((!bus.iorq && !bus.mreq) || bus.rfsh || clkwait), + .fetch_allow((!bus.iorq && !bus.mreq) || bus.rfsh || (clkwait && turbo == TURBO_NONE)), .fetch(screen_fetch), .addr(screen_addr), .fetch_next(screen_fetch_next), @@ -212,9 +214,8 @@ cpucontrol cpucontrol0( .hc(hc), .rampage128(rampage128), .machine(machine), - .screen_contention(screen_contention), .turbo(turbo), - .ext_wait_cycle(div_wait), + .screen_contention(screen_contention), .init_done_in(init_done), .n_rstcpu(n_rstcpu), @@ -411,8 +412,7 @@ divmmc divmmc0( .map(div_map), .automap(div_automap), .ram(div_ram), - .ramwr_mask(div_ramwr_mask), - .cpuwait(div_wait) + .ramwr_mask(div_ramwr_mask) ); assign sd_mosi_tape_out = (!divmmc_en && !zc_en)? tape_out : sd_mosi0; diff --git a/fpga/syn/clocks.sdc b/fpga/syn/clocks.sdc index 60ab9bf..4661557 100755 --- a/fpga/syn/clocks.sdc +++ b/fpga/syn/clocks.sdc @@ -8,10 +8,13 @@ derive_clocks -period 14MHz set_multicycle_path -from {vencode:*|*} -to {vencode:*|*} -setup 4 set_multicycle_path -from {vencode:*|*} -to {vencode:*|*} -hold 3 - -# One screen read cycle = ~71ns. SRAM speed = 55ns -# So we have about 16ns to setup control signals (n_vrd, n_vwr, va - 10ns) and read back data (vd - 6ns) -set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vrd] 10ns -set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vwr] 10ns -set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports va[*]] 10ns -set_max_delay -from [get_ports vd[*]] -to [get_pins -compatibility_mode screen0|*] 6ns + +# One screen read cycle = ~71ns. SRAM speed = 55ns +# So we have about 16ns to setup control signals (n_vrd, n_vwr, va - 10ns) and read back data (vd - 6ns) +set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vrd] 10ns +set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vwr] 10ns +set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports va[*]] 10ns +set_max_delay -from [get_ports vd[*]] -to [get_pins -compatibility_mode screen0|*] 6ns + +set_false_path -from * -to [get_ports {snd_l}] +set_false_path -from * -to [get_ports {snd_r}] diff --git a/fpga/syn/rev_A.qsf b/fpga/syn/rev_A.qsf index 123c9dc..f6d0a98 100644 --- a/fpga/syn/rev_A.qsf +++ b/fpga/syn/rev_A.qsf @@ -58,7 +58,7 @@ set_global_assignment -name FMAX_REQUIREMENT "4 MHz" -section_id clk4 set_instance_assignment -name CLOCK_SETTINGS clk8 -to "lpm_counter:wgcnt_rtl_1|dffs[1]" set_instance_assignment -name CLOCK_SETTINGS clk4 -to "lpm_counter:wgcnt_rtl_1|dffs[2]" -set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" set_global_assignment -name FITTER_EFFORT "STANDARD FIT" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output/ set_global_assignment -name FMAX_REQUIREMENT "7.156 MHz" -section_id clk7 @@ -67,7 +67,7 @@ set_global_assignment -name DUTY_CYCLE 40 -section_id clk7 set_global_assignment -name SAVE_DISK_SPACE OFF set_global_assignment -name SMART_RECOMPILE ON set_global_assignment -name POWER_USE_PVA OFF -set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF set_global_assignment -name DEVICE_FILTER_PIN_COUNT 100 @@ -165,7 +165,6 @@ set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to vd[5] set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to vd[6] set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to vd[7] set_global_assignment -name VERILOG_MACRO "REV_A=" -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ym2149.sv set_global_assignment -name VERILOG_FILE ../rtl/vencode_sin_cos.v set_global_assignment -name VHDL_FILE ../rtl/vencode.vhd @@ -188,4 +187,14 @@ set_global_assignment -name SDC_FILE clocks.sdc set_global_assignment -name CDF_FILE output/zx_ula.cdf set_global_assignment -name QIP_FILE ip/pll.qip set_global_assignment -name QIP_FILE ip/rom2ram.qip -set_global_assignment -name QIP_FILE ip/asmi.qip \ No newline at end of file +set_global_assignment -name QIP_FILE ip/asmi.qip +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON +set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/fpga/syn/rev_B.qsf b/fpga/syn/rev_B.qsf index c389655..cda07ef 100644 --- a/fpga/syn/rev_B.qsf +++ b/fpga/syn/rev_B.qsf @@ -58,7 +58,7 @@ set_global_assignment -name FMAX_REQUIREMENT "4 MHz" -section_id clk4 set_instance_assignment -name CLOCK_SETTINGS clk8 -to "lpm_counter:wgcnt_rtl_1|dffs[1]" set_instance_assignment -name CLOCK_SETTINGS clk4 -to "lpm_counter:wgcnt_rtl_1|dffs[2]" -set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" set_global_assignment -name FITTER_EFFORT "STANDARD FIT" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output/ set_global_assignment -name FMAX_REQUIREMENT "7.156 MHz" -section_id clk7 @@ -67,7 +67,7 @@ set_global_assignment -name DUTY_CYCLE 40 -section_id clk7 set_global_assignment -name SAVE_DISK_SPACE OFF set_global_assignment -name SMART_RECOMPILE ON set_global_assignment -name POWER_USE_PVA OFF -set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF set_global_assignment -name DEVICE_FILTER_PIN_COUNT 100 @@ -187,5 +187,14 @@ set_global_assignment -name CDF_FILE output/zx_ula.cdf set_global_assignment -name QIP_FILE ip/pll.qip set_global_assignment -name QIP_FILE ip/rom2ram.qip set_global_assignment -name QIP_FILE ip/asmi.qip -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -set_global_assignment -name VERILOG_MACRO "REV_B=" \ No newline at end of file +set_global_assignment -name VERILOG_MACRO "REV_B=" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON +set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/fpga/syn/rev_zero_A.qsf b/fpga/syn/rev_zero_A.qsf index bcd77a6..d1b9d35 100644 --- a/fpga/syn/rev_zero_A.qsf +++ b/fpga/syn/rev_zero_A.qsf @@ -58,7 +58,7 @@ set_global_assignment -name FMAX_REQUIREMENT "4 MHz" -section_id clk4 set_instance_assignment -name CLOCK_SETTINGS clk8 -to "lpm_counter:wgcnt_rtl_1|dffs[1]" set_instance_assignment -name CLOCK_SETTINGS clk4 -to "lpm_counter:wgcnt_rtl_1|dffs[2]" -set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" set_global_assignment -name FITTER_EFFORT "STANDARD FIT" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output/ set_global_assignment -name FMAX_REQUIREMENT "7.156 MHz" -section_id clk7 @@ -67,7 +67,7 @@ set_global_assignment -name DUTY_CYCLE 40 -section_id clk7 set_global_assignment -name SAVE_DISK_SPACE OFF set_global_assignment -name SMART_RECOMPILE ON set_global_assignment -name POWER_USE_PVA OFF -set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF set_global_assignment -name DEVICE_FILTER_PIN_COUNT 100 @@ -189,10 +189,13 @@ set_global_assignment -name QIP_FILE ip/rom2ram.qip set_global_assignment -name QIP_FILE ip/asmi.qip set_global_assignment -name VERILOG_MACRO "REV_ZERO_A=" set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to clkcpu -set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF -set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF -set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING OFF -set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF -set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA OFF -set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file