summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2016-11-12 05:51:40 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2016-11-12 05:51:40 (GMT)
commit7808cfffc1fb571a5dfea6bed502dad890d076fc (patch)
treec9b83e2f7c04ad169122fab688ec18bc9b15d1d5
parentf0677d301655d07a4df9ba92eabde2311bfc67f3 (diff)
downloadabc80-7808cfffc1fb571a5dfea6bed502dad890d076fc.zip
abc80-7808cfffc1fb571a5dfea6bed502dad890d076fc.tar.gz
abc80-7808cfffc1fb571a5dfea6bed502dad890d076fc.tar.bz2
abc80-7808cfffc1fb571a5dfea6bed502dad890d076fc.tar.xz
Improve sdram timing by enabling I/O cell packing; fgpage 5
Further improve SRAM timing by using the flipflops in the I/O cells for input, too. Change the default fgpage to 5 so it doesn't conflict with the default location for the 80-character BASIC in RAM. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--abc80.qsf6
-rw-r--r--abc80.sdc4
-rw-r--r--abc80.v100
3 files changed, 80 insertions, 30 deletions
diff --git a/abc80.qsf b/abc80.qsf
index 5b54b42..5507830 100644
--- a/abc80.qsf
+++ b/abc80.qsf
@@ -352,7 +352,7 @@ set_global_assignment -name AUTO_PACKED_REGISTERS_CYCLONE AUTO
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON
-set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
+set_global_assignment -name FITTER_EFFORT "AUTO FIT"
set_global_assignment -name INC_PLC_MODE OFF
set_global_assignment -name ROUTING_BACK_ANNOTATION_MODE OFF
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD LVTTL
@@ -621,4 +621,8 @@ set_global_assignment -name SOURCE_FILE db/abc80.cmp.rdb
set_global_assignment -name SIGNALTAP_FILE stp2.stp
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:data/revrom.tcl"
+set_global_assignment -name OPTIMIZE_IOC_REGISTER_PLACEMENT_FOR_TIMING "PACK ALL IO REGISTERS"
+set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION ALWAYS
+set_global_assignment -name AUTO_PACKED_REGISTERS_STRATIXII "SPARSE AUTO"
+set_global_assignment -name RTLV_GROUP_RELATED_NODES_TMV ON
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file
diff --git a/abc80.sdc b/abc80.sdc
index 3dbab3b..cd9197f 100644
--- a/abc80.sdc
+++ b/abc80.sdc
@@ -18,9 +18,9 @@ set_clock_groups -asynchronous \
-group {clock_27[*]}
set_multicycle_path -from [get_keepers {mmuram*q_a[*]}] -to [get_keepers {sram_*_q*}] 4
-set_multicycle_path -start -from [get_keepers {msel[*] mselrd[*] mselwr[*]}] -to [get_clocks {pll1|*|clk[2]}] 2
+set_multicycle_path -start -from [get_keepers {msel*[*]}] -to [get_clocks {pll1|*|clk[2]}] 2
set_multicycle_path -from [get_clocks {pll1|*|clk[2]}] -to [get_keepers {sram_*_q*}] 2
-set_multicycle_path -start -from [get_keepers {sram_do*}] -to [get_clocks {pll1|*|clk[1] pll1|*|clk[2]}] 2
+set_multicycle_path -start -from [get_keepers {sram_q[*]}] -to [get_clocks {pll1|*|clk[1] pll1|*|clk[2]}] 2
# I/O pin constraints
set_input_delay -clock {pll1|*|clk[0]} -min 0ns [get_ports {sram_dq[*]}]
diff --git a/abc80.v b/abc80.v
index 411f2cc..f9218ca 100644
--- a/abc80.v
+++ b/abc80.v
@@ -61,6 +61,7 @@ module abc80 (
output sram_we_n, // SRAM WE#
output [1:0] sram_be_n, // SRAM LB#, UB#
output [17:0] sram_a, // SRAM address bus
+ (* altera_attribute="-name FAST_OUTPUT_REGISTER ON; -name FAST_OUTPUT_ENABLE_REGISTER ON; -name FAST_INPUT_REGISTER ON" *)
inout [15:0] sram_dq, // SRAM data bus
output sd_clk, // SD card clock
@@ -266,7 +267,6 @@ module abc80 (
reg [5:0] fgxaddr; // Byte address horizontally
reg [8:0] fgyaddr; // Byte address vertically x 2 (see below)
- reg [7:0] sram_fgdata;
reg sram_fgack;
wire fgfull;
wire [4:0] fgwrusedw; // FIFO fill status
@@ -495,8 +495,8 @@ module abc80 (
always @(posedge sram_clk)
sram_clk_phase <= sram_clk_next_phase;
- wire [7:0] sram_q; // Data out from sram
- reg [7:0] sram_do; // Latched output data from sram
+ reg [7:0] sram_do_q; // Output data to CPU
+ reg [7:0] sram_fgdata_q; // Output data to fg unit
reg sram_fg_q; // Data is for the fg unit
reg sram_cpu_q; // Data is for the CPU
reg sram_ce_q;
@@ -504,7 +504,18 @@ module abc80 (
reg sram_we_q;
reg sram_fgrd;
reg [18:0] sram_addr_q;
- reg [7:0] sram_d_q; // Output data (from write)
+ reg [1:0] sram_be_q;
+ reg [15:0] sram_d_q; // Output data (from write)
+ reg [15:0] sram_d_en;
+ reg [15:0] sram_q; // Latched input data (in I/O pad)
+
+ reg sram_mux_ctl; // addr[0] with a delay
+
+ // SRAM input mux
+ wire [7:0] sram_mux_out = sram_mux_ctl ? sram_q[15:8] : sram_q[7:0];
+
+ wire [7:0] sram_do = sram_cpu_q ? sram_mux_out : sram_do_q;
+ wire [7:0] sram_fgdata = sram_fg_q ? sram_mux_out : sram_fgdata_q;
// Are we actually accessed by the CPU? Use msel_q[] here rather than
// msel[] to save two sram_clk cycles.
@@ -516,31 +527,39 @@ module abc80 (
always @(negedge rst_n or posedge sram_clk)
if ( ~rst_n )
begin
- sram_ce_q <= 1'b0;
- sram_oe_q <= 1'b0;
- sram_we_q <= 1'b0;
- sram_fg_q <= 1'b0;
- sram_cpu_q <= 1'b0;
- sram_addr_q <= 19'bx;
- sram_d_q <= 8'bx;
- sram_do <= 8'bx;
- sram_fgdata <= 8'bx;
- npled_do <= 8'bx;
+ sram_ce_q <= 1'b0;
+ sram_oe_q <= 1'b0;
+ sram_we_q <= 1'b0;
+ sram_d_en <= ~16'b0;
+ sram_fg_q <= 1'b0;
+ sram_cpu_q <= 1'b0;
+ sram_addr_q <= 19'bx;
+ sram_be_q <= 2'b00;
+ sram_d_q <= 16'bx;
+ sram_q <= 16'bx;
+ sram_do_q <= 8'bx;
+ sram_fgdata_q <= 8'bx;
+ npled_do <= 8'bx;
end // if ( ~rst_n )
else
begin
case (sram_clk_phase)
+ 3'd0:
+ sram_mux_ctl <= sram_addr_q[0];
+
3'd1:
begin
- npled_do <= sram_q;
- sram_d_q <= cpu_do;
+ sram_q <= sram_dq;
+ sram_d_q <= { cpu_do, cpu_do };
if (sram_cpu)
begin
sram_ce_q <= 1'b1;
sram_we_q <= ~cpu_wr_n & ~mmu_ro;
sram_oe_q <= ~cpu_rd_n;
+ sram_d_en <= {16{cpu_rd_n}};
sram_addr_q <= mmu_a[18:0];
+ sram_be_q <= {mmu_a[0], ~mmu_a[0]};
sram_cpu_q <= 1'b1;
sram_fg_q <= 1'b0;
end
@@ -549,7 +568,9 @@ module abc80 (
sram_ce_q <= 1'b1;
sram_we_q <= 1'b0;
sram_oe_q <= 1'b1;
+ sram_d_en <= 16'b0;
sram_addr_q <= sram_fgaddr;
+ sram_be_q <= {sram_fgaddr[0], ~sram_fgaddr[0]};
sram_cpu_q <= 1'b0;
sram_fg_q <= 1'b1;
end
@@ -558,12 +579,20 @@ module abc80 (
sram_ce_q <= 1'b0;
sram_we_q <= 1'b0;
sram_oe_q <= 1'b0;
+ sram_d_en <= ~16'b0; // Don't float the bus
sram_addr_q <= 19'bx;
+ sram_be_q <= 2'b00;
sram_cpu_q <= 1'b0;
sram_fg_q <= 1'b0;
end // else: !if(sram_fgrd)
end
+ 3'd2:
+ begin
+ npled_do <= sram_mux_out;
+ sram_mux_ctl <= sram_addr_q[0];
+ end
+
3'd4:
begin
sram_we_q <= 1'b0;
@@ -571,17 +600,31 @@ module abc80 (
3'd5:
begin
- if (sram_fg_q)
- sram_fgdata <= sram_q;
- if (sram_cpu_q)
- sram_do <= sram_q;
+ sram_q <= sram_dq;
sram_ce_q <= 1'b0;
sram_we_q <= 1'b0;
sram_oe_q <= 1'b0;
+ sram_be_q <= 2'b00;
+ sram_d_en <= ~16'b0; // Don't float the bus
+ sram_d_q <= cpu_do; // For better I/O packing
sram_addr_q <= npled_addr;
end
+ 3'd6:
+ begin
+ if (sram_cpu_q)
+ sram_do_q <= sram_mux_out;
+ if (sram_fg_q)
+ sram_fgdata_q <= sram_mux_out;
+ end
+
+ 3'd7:
+ begin
+ sram_cpu_q <= 1'b0;
+ sram_fg_q <= 1'b0;
+ end
+
default:
begin
// Do nothing
@@ -591,17 +634,20 @@ module abc80 (
// Driving output pins.
- assign sram_a = sram_addr_q[18:1];
- assign sram_be_n = ~{sram_addr_q[0], ~sram_addr_q[0]};
+ assign sram_a = sram_addr_q;
+ assign sram_be_n = ~sram_be_q;
assign sram_ce_n = ~sram_ce_q;
assign sram_oe_n = ~sram_oe_q;
assign sram_we_n = ~sram_we_q;
- assign sram_dq = ~sram_oe_q ? { sram_d_q, sram_d_q } : 16'bz;
-
- // SRAM Input side MUX
- assign sram_q = sram_addr_q[0] ? sram_dq[15:8] : sram_dq[7:0];
+ genvar i;
+ generate
+ for (i = 0; i < 16; i=i+1)
+ begin: gen_sram_dq
+ assign sram_dq[i] = sram_d_en[i] ? sram_d_q[i] : 1'bz;
+ end
+ endgenerate
always @(negedge rst_n or posedge cpu_clk)
if ( ~rst_n )
@@ -1189,7 +1235,7 @@ module abc80 (
intio_do <= ~8'b0;
fgctl <= 8'h00;
- fgpage <= 5'h04;
+ fgpage <= 5'h05; // After BASIC80 in RAM
gpio_dat <= 36'b0;
gpio_ctl <= 36'b0;