From 568f59017164ccd8c70e09e676af6d05249d7f91 Mon Sep 17 00:00:00 2001 From: Eugene Lozovoy Date: Tue, 9 Aug 2022 12:49:27 +0300 Subject: [PATCH] fix random garbage on screen (again) I hope I've found and fixed root cause of issue in this commit. --- fpga/rtl/screen.sv | 16 +++++++++------- fpga/rtl/turbosound.sv | 24 +++++++++++++++++------- fpga/syn/clocks.sdc | 7 +++++++ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/fpga/rtl/screen.sv b/fpga/rtl/screen.sv index 175f7fc..7f4b508 100755 --- a/fpga/rtl/screen.sv +++ b/fpga/rtl/screen.sv @@ -17,7 +17,7 @@ module screen( input fetch_allow, output reg fetch, output fetch_next, - output [14:0] addr, + output reg [14:0] addr, input [7:0] fetch_data, output contention, @@ -184,7 +184,7 @@ wire screen_show = (vc < V_AREA) && (hc0 >= (SCREEN_DELAY<<2) - 1) && (hc0 < ((H wire screen_update = hc0[4:0] == 5'b10011; wire border_update = (hc0[4:0] == 5'b10011) || (machine == MACHINE_PENT && ck7); wire bitmap_shift = hc0[1:0] == 2'b11; -wire next_addr = hc0[4:0] == 5'b10001; +wire next_addr = hc0[4:0] == 5'b10000; reg [7:0] vaddr; reg [7:3] haddr; @@ -214,18 +214,16 @@ 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 == 2'd0; -wire fetch_attr = fetch && fetch_step == 2'd1; +wire fetch_bitmap = fetch && fetch_step == 1'd0; +wire fetch_attr = fetch && fetch_step == 1'd1; assign fetch_next = loading && fetch_allow; -assign addr = fetch_bitmap? - { 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 = { attr_next[7:6], 1'b0, attr_next[2:0] }; assign up_paper_addr = { attr_next[7:6], 1'b1, attr_next[5:3] }; always @(posedge clk28 or negedge rst_n) begin if (!rst_n) begin + addr <= 0; fetch <= 0; fetch_step <= 0; attr <= 0; @@ -237,6 +235,10 @@ always @(posedge clk28 or negedge rst_n) begin 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; diff --git a/fpga/rtl/turbosound.sv b/fpga/rtl/turbosound.sv index fbad16f..6dfb49f 100644 --- a/fpga/rtl/turbosound.sv +++ b/fpga/rtl/turbosound.sv @@ -7,8 +7,8 @@ module turbosound( input en_ts, cpu_bus bus, - output [7:0] d_out, - output d_out_active, + output reg [7:0] d_out, + output reg d_out_active, output [7:0] ay_a0, output [7:0] ay_b0, @@ -18,12 +18,15 @@ module turbosound( output [7:0] ay_c1 ); +// bdir bc1 description +// bffd read | 0 0 inactive +// bffd write | 1 0 write to psg +// fffd read | 0 1 read from psg +// fffd write | 1 1 latch address reg ay_bdir; reg ay_bc1; reg ay_sel; -wire ay_rd0 = bus.rd && ay_bc1 == 1'b1 && ay_bdir == 1'b0 && ay_sel == 1'b0; -wire ay_rd1 = bus.rd && ay_bc1 == 1'b1 && ay_bdir == 1'b0 && ay_sel == 1'b1; wire port_bffd = en && bus.ioreq && bus.a_reg[15] == 1'b1 && bus.a_reg[1] == 0; wire port_fffd = en && bus.ioreq && bus.a_reg[15] == 1'b1 && bus.a_reg[14] == 1'b1 && bus.a_reg[1] == 0; always @(posedge clk28 or negedge rst_n) begin @@ -87,8 +90,15 @@ YM2149 ym2149_1( ); -assign d_out_active = ay_rd0 | ay_rd1; -assign d_out = ay_rd1? ay_dout1 : ay_dout0; - +always @(posedge clk28 or negedge rst_n) begin + if (!rst_n) begin + d_out_active <= 0; + d_out <= 0; + end + else begin + d_out_active <= bus.rd && port_fffd; + d_out <= ay_sel? ay_dout1 : ay_dout0; + end +end endmodule diff --git a/fpga/syn/clocks.sdc b/fpga/syn/clocks.sdc index 1a5036d..60ab9bf 100755 --- a/fpga/syn/clocks.sdc +++ b/fpga/syn/clocks.sdc @@ -8,3 +8,10 @@ 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