summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaptor Engineering Development Team <support@raptorengineering.com>2018-01-12 06:40:59 -0600
committerRaptor Engineering Development Team <support@raptorengineering.com>2018-01-12 06:41:59 -0600
commit24815a68ff312998314886365affa6234990b594 (patch)
tree453fd6dbe6b67920736e10eb6be44151652d3124
parentdc87ab2b3d954262cb9490894e2f36860c313936 (diff)
downloadtalos-system-fpga-24815a68ff312998314886365affa6234990b594.tar.gz
talos-system-fpga-24815a68ff312998314886365affa6234990b594.zip
Convert combinatorial logic to registered logic to work around apparent Yosys bug
Add initial internal oscillator Fix license in PCF file Tested to work on initial Talos™ II hardware
-rw-r--r--Makefile7
-rw-r--r--main.v283
-rw-r--r--system_fpga.pcf24
3 files changed, 201 insertions, 113 deletions
diff --git a/Makefile b/Makefile
index 03e3dca..de4a43a 100644
--- a/Makefile
+++ b/Makefile
@@ -59,7 +59,7 @@ system_fpga.int: system_fpga_1.tmg system_fpga_2.tmg system_fpga_3.tmg system_fp
for trial in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64; do \
CURRENT_TRIAL_RESULT=$$(cat system_fpga_$${trial}.tmg | grep "Total path delay" | awk '{print $$6}' | sed 's/(//g'); \
if [ "$$CURRENT_TRIAL_RESULT" != "" ]; then \
- echo "system_fpga_$${trial}.tmg : $$CURRENT_TRIAL_RESULT"; \
+ echo "system_fpga_$${trial}.tmg : $$CURRENT_TRIAL_RESULT"; \
COMPARISON_RESULT=$$(echo "$$CURRENT_TRIAL_RESULT > $$BEST_TRIAL_RESULT" | bc -l); \
if [ $$COMPARISON_RESULT -eq 1 ]; then \
BEST_TRIAL=system_fpga_$${trial}.tmg; \
@@ -67,6 +67,11 @@ system_fpga.int: system_fpga_1.tmg system_fpga_2.tmg system_fpga_3.tmg system_fp
fi; \
fi; \
done; \
+ if [ "$$BEST_TRIAL_RESULT" -eq "0" ]; then \
+ echo "Unable to determine fastest result. Selecting first run...."; \
+ BEST_TRIAL=system_fpga_1.tmg; \
+ BEST_TRIAL_RESULT=0; \
+ fi; \
echo "Fastest result: $$BEST_TRIAL : $$BEST_TRIAL_RESULT"; \
cp `echo $$BEST_TRIAL | sed 's/\.tmg/\.int/g'` system_fpga.int; \
cp $$BEST_TRIAL system_fpga.tmg
diff --git a/main.v b/main.v
index 81ac5e3..9ec3f7f 100644
--- a/main.v
+++ b/main.v
@@ -11,30 +11,30 @@ module system_fpga_top
// General I/O
input wire sysen,
- output wire sysgood,
+ output reg sysgood,
input wire debug_in,
// DD1 temp fix for VCS overcurrent bug
input wire seq_cont,
// Enable outputs
- output wire vdda_en,
- output wire vddb_en,
- output wire vcsa_en,
- output wire vcsb_en,
- output wire vdna_en,
- output wire vdnb_en,
- output wire vioa_en,
- output wire viob_en,
- output wire vppab_en,
- output wire vppcd_en,
- output wire vddrab_en,
- output wire vttab_en,
- output wire vddrcd_en,
- output wire vttcd_en,
- output wire avdd_en,
- output wire miscio_en,
- output wire atx_en,
+ output reg vdda_en,
+ output reg vddb_en,
+ output reg vcsa_en,
+ output reg vcsb_en,
+ output reg vdna_en,
+ output reg vdnb_en,
+ output reg vioa_en,
+ output reg viob_en,
+ output reg vppab_en,
+ output reg vppcd_en,
+ output reg vddrab_en,
+ output reg vttab_en,
+ output reg vddrcd_en,
+ output reg vttcd_en,
+ output reg avdd_en,
+ output reg miscio_en,
+ output reg atx_en,
// Power Good inputs
input wire vdda_pg,
@@ -64,22 +64,22 @@ module system_fpga_top
output wire cpub_clk_oeb,
// Resets
- output wire lpc_rst,
+ output reg lpc_rst,
input wire bmc_software_pg,
- output wire bmc_rst,
- output wire fan_rst,
- output wire usbhub_rst,
- output wire cpu_stby_rst,
+ output reg bmc_rst,
+ output reg fan_rst,
+ output reg usbhub_rst,
+ output reg cpu_stby_rst,
// Reserved for future use
- output wire dual_5v_ctrl,
- output wire window_open_n,
+ output reg dual_5v_ctrl,
+ output reg window_open_n,
// BMC system reset signalling
- output wire bmc_system_reset_request_n,
+ output reg bmc_system_reset_request_n,
// Component disable lines
- output wire pmc_disable_n,
+ output reg pmc_disable_n,
// System status lines
input wire nic1_act_led_n,
@@ -137,24 +137,26 @@ module system_fpga_top
parameter vendor_id2 = 8'h43;
parameter vendor_id3 = 8'h53;
parameter vendor_id4 = 8'h20;
- parameter rail_size = 15;
- wire [rail_size - 1:0] en_buf = 1'b0;
- wire [rail_size - 1:0] pg_buf;
- wire sysgood_buf;
+ parameter RAIL_SIZE = 15;
+ reg [RAIL_SIZE - 1:0] en_buf = {RAIL_SIZE{1'b0}};
+ reg [RAIL_SIZE - 1:0] pg_buf;
+ reg sysgood_buf;
wire clk_in;
+ wire clk_in_lpc;
+ wire clk_in_ring;
wire stdby_sed;
- wire sysen_buf;
- parameter railarray_0 = 1'b0;
- parameter railarray_1 = 1'b1; // synchronizing signals
- reg [rail_size - 1:0] pg_s1 = 1'b0;
- reg [rail_size - 1:0] pg_s2 = 1'b0;
+ reg sysen_buf;
+ parameter railarray_0 = {RAIL_SIZE{1'b0}};
+ parameter railarray_1 = {RAIL_SIZE{1'b1}}; // synchronizing signals
+ reg [RAIL_SIZE - 1:0] pg_s1 = {RAIL_SIZE{1'b0}};
+ reg [RAIL_SIZE - 1:0] pg_s2 = {RAIL_SIZE{1'b0}};
reg sysen_s1 = 1'b0;
reg sysen_s2 = 1'b0;
reg seq_s1 = 1'b1;
reg seq_s2 = 1'b1; // Timer (Watchdog and Delay) signals
- reg [rail_size - 1:0] delay_done = 1'b0;
- reg [23:0] w_count = 1'b0;
- reg [16:0] d_count = 1'b0; // at 4.16MHz, w_count(23) being one means approximately 100ms have passed, good for checking watchdog between EN and PG
+ reg [RAIL_SIZE - 1:0] delay_done = {RAIL_SIZE{1'b0}};
+ reg [23:0] w_count = 0;
+ reg [16:0] d_count = 0; // at 4.16MHz, w_count(23) being one means approximately 100ms have passed, good for checking watchdog between EN and PG
// d_count(16) being one means approximately 15ms have passed, good enough for delay betwen one rail and the next
reg wait_err = 1'b0;
reg operation_err = 1'b0;
@@ -188,12 +190,43 @@ module system_fpga_top
wire panel_uid_led_std;
reg [2:0] bmc_startup_kr = 3'b000;
+ // Implement nasty ring oscillator for fallback use when main system clock is offline
+ // Thanks to Clifford Wolf for the idea and basic code!
+ wire chain_in;
+ wire chain_out;
+ wire [99:0] buffers_in;
+ wire [99:0] buffers_out;
+ assign buffers_in = {buffers_out[98:0], chain_in};
+ assign chain_out = buffers_out[99];
+ assign chain_in = !chain_out;
+
+ SB_LUT4 #(
+ .LUT_INIT(16'd2)
+ ) buffers [99:0] (
+ .O(buffers_out),
+ .I0(buffers_in),
+ .I1(1'b0),
+ .I2(1'b0),
+ .I3(1'b0)
+ );
+
+ // Divide unstable 10MHz ring clock down to ~2MHz
+ reg [2:0] ring_clock_divider;
+ always @(posedge chain_out) begin
+ ring_clock_divider = ring_clock_divider + 1;
+ end
+ assign clk_in_ring = ring_clock_divider[2];
+
// Divide input 33MHz clock down to 4.125MHz
- reg [2:0] clock_divider;
+ reg [2:0] lpc_clock_divider;
always @(posedge lpc_clock) begin
- clock_divider = clock_divider + 1;
+ lpc_clock_divider = lpc_clock_divider + 1;
end
- assign clk_in = clock_divider[2];
+ assign clk_in_lpc = lpc_clock_divider[2];
+
+ reg clock_select = 1'b1;
+
+ assign clk_in = (clock_select)?clk_in_ring:clk_in_lpc;
// I2C device
i2c_slave #(
@@ -318,7 +351,7 @@ module system_fpga_top
else if ((sysen_s2 == 1'b0 || err_found == 1'b1)) begin
w_count <= {24{1'b0}};
d_count <= {17{1'b0}};
- delay_done <= {(((rail_size - 1))-((0))+1){1'b0}};
+ delay_done <= {(((RAIL_SIZE - 1))-((0))+1){1'b0}};
end
else if ((pg_s2[0] == 1'b1 && en_buf[0] == 1'b1 && delay_done[0] == 1'b0)) begin
w_count <= {24{1'b0}};
@@ -559,100 +592,128 @@ module system_fpga_top
end
// Assign Ports to Enables
- assign atx_en = ~en_buf[0];
- assign miscio_en = en_buf[1];
- assign vdna_en = en_buf[2];
- assign vdnb_en = en_buf[3] & ~cpub_present_n;
- assign avdd_en = en_buf[4];
- assign vioa_en = en_buf[5];
- assign viob_en = en_buf[6] & ~cpub_present_n;
- assign vdda_en = en_buf[7];
- assign vddb_en = en_buf[8] & ~cpub_present_n;
- assign vcsa_en = en_buf[9];
- assign vcsb_en = en_buf[10] & ~cpub_present_n;
- assign vppab_en = en_buf[11];
- assign vppcd_en = en_buf[12] & ~cpub_present_n;
- assign vddrab_en = en_buf[13];
- assign vttab_en = en_buf[13];
- assign vddrcd_en = en_buf[14] & ~cpub_present_n;
- assign vttcd_en = en_buf[14] & ~cpub_present_n;
+ always @(posedge clk_in) begin
+ atx_en = ~en_buf[0];
+ miscio_en = en_buf[1];
+ vdna_en = en_buf[2];
+ vdnb_en = en_buf[3] & ~cpub_present_n;
+ avdd_en = en_buf[4];
+ vioa_en = en_buf[5];
+ viob_en = en_buf[6] & ~cpub_present_n;
+ vdda_en = en_buf[7];
+ vddb_en = en_buf[8] & ~cpub_present_n;
+ vcsa_en = en_buf[9];
+ vcsb_en = en_buf[10] & ~cpub_present_n;
+ vppab_en = en_buf[11];
+ vppcd_en = en_buf[12] & ~cpub_present_n;
+ vddrab_en = en_buf[13];
+ vttab_en = en_buf[13];
+ vddrcd_en = en_buf[14] & ~cpub_present_n;
+ vttcd_en = en_buf[14] & ~cpub_present_n;
+ end
// Assign Ports to PGood buffer
- assign pg_buf[0] = atx_pg;
- assign pg_buf[1] = miscio_pg;
- assign pg_buf[2] = vdna_pg;
- assign pg_buf[3] = vdnb_pg | (cpub_present_n & en_buf[3]);
- assign pg_buf[4] = avdd_pg;
- assign pg_buf[5] = vioa_pg;
- assign pg_buf[6] = viob_pg | (cpub_present_n & en_buf[6]);
- assign pg_buf[7] = vdda_pg;
- assign pg_buf[8] = vddb_pg | (cpub_present_n & en_buf[8]);
- assign pg_buf[9] = vcsa_pg;
- assign pg_buf[10] = vcsb_pg | (cpub_present_n & en_buf[10]);
- assign pg_buf[11] = vppab_pg;
- assign pg_buf[12] = vppcd_pg | (cpub_present_n & en_buf[12]);
- assign pg_buf[13] = vddrab_pg;
- assign pg_buf[14] = vddrcd_pg | (cpub_present_n & en_buf[14]);
+ always @(posedge clk_in) begin
+ pg_buf[0] = atx_pg;
+ pg_buf[1] = miscio_pg;
+ pg_buf[2] = vdna_pg;
+ pg_buf[3] = vdnb_pg | (cpub_present_n & en_buf[3]);
+ pg_buf[4] = avdd_pg;
+ pg_buf[5] = vioa_pg;
+ pg_buf[6] = viob_pg | (cpub_present_n & en_buf[6]);
+ pg_buf[7] = vdda_pg;
+ pg_buf[8] = vddb_pg | (cpub_present_n & en_buf[8]);
+ pg_buf[9] = vcsa_pg;
+ pg_buf[10] = vcsb_pg | (cpub_present_n & en_buf[10]);
+ pg_buf[11] = vppab_pg;
+ pg_buf[12] = vppcd_pg | (cpub_present_n & en_buf[12]);
+ pg_buf[13] = vddrab_pg;
+ pg_buf[14] = vddrcd_pg | (cpub_present_n & en_buf[14]);
+ end
// Enable outputs
// Shut everything off if an error has occurred
// Otherwise, if system enable is up, then enable short delay is done after previous rail
// Otherwise, disable after next rail goes down
- assign en_buf[0] = (sysen_s2 | pg_s2[1]) & ~err_found;
- assign en_buf[1] = ((sysen_s2 & delay_done[0]) | pg_s2[2]) & ~err_found;
- assign en_buf[2] = ((sysen_s2 & delay_done[1]) | pg_s2[3]) & ~err_found;
- assign en_buf[3] = ((sysen_s2 & delay_done[2]) | pg_s2[4]) & ~err_found;
- assign en_buf[4] = ((sysen_s2 & delay_done[ + 1]) | pg_s2[ + 1]) & ~err_found;
- assign en_buf[5] = ((sysen_s2 & delay_done[4]) | pg_s2[6]) & ~err_found;
- assign en_buf[6] = ((sysen_s2 & delay_done[5]) | pg_s2[7]) & ~err_found;
- assign en_buf[7] = ((sysen_s2 & delay_done[6]) | pg_s2[8]) & ~err_found;
- assign en_buf[8] = ((sysen_s2 & delay_done[7]) | pg_s2[9]) & ~err_found;
- assign en_buf[9] = (( ~seq_s2 & sysen_s2 & delay_done[8]) | pg_s2[10]) & ~err_found;
- assign en_buf[10] = ((sysen_s2 & delay_done[9]) | pg_s2[11]) & ~err_found;
- assign en_buf[11] = ((sysen_s2 & delay_done[10]) | pg_s2[12]) & ~err_found;
- assign en_buf[12] = ((sysen_s2 & delay_done[11]) | pg_s2[13]) & ~err_found;
- assign en_buf[13] = ((sysen_s2 & delay_done[12]) | pg_s2[14]) & ~err_found;
- assign en_buf[14] = (sysen_s2 & delay_done[13]) & ~err_found;
+ always @(posedge clk_in) begin
+ en_buf[0] = (sysen_s2 | pg_s2[1]) & ~err_found;
+ en_buf[1] = ((sysen_s2 & delay_done[0]) | pg_s2[2]) & ~err_found;
+ en_buf[2] = ((sysen_s2 & delay_done[1]) | pg_s2[3]) & ~err_found;
+ en_buf[3] = ((sysen_s2 & delay_done[2]) | pg_s2[4]) & ~err_found;
+ en_buf[4] = ((sysen_s2 & delay_done[ + 1]) | pg_s2[ + 1]) & ~err_found;
+ en_buf[5] = ((sysen_s2 & delay_done[4]) | pg_s2[6]) & ~err_found;
+ en_buf[6] = ((sysen_s2 & delay_done[5]) | pg_s2[7]) & ~err_found;
+ en_buf[7] = ((sysen_s2 & delay_done[6]) | pg_s2[8]) & ~err_found;
+ en_buf[8] = ((sysen_s2 & delay_done[7]) | pg_s2[9]) & ~err_found;
+ en_buf[9] = (( ~seq_s2 & sysen_s2 & delay_done[8]) | pg_s2[10]) & ~err_found;
+ en_buf[10] = ((sysen_s2 & delay_done[9]) | pg_s2[11]) & ~err_found;
+ en_buf[11] = ((sysen_s2 & delay_done[10]) | pg_s2[12]) & ~err_found;
+ en_buf[12] = ((sysen_s2 & delay_done[11]) | pg_s2[13]) & ~err_found;
+ en_buf[13] = ((sysen_s2 & delay_done[12]) | pg_s2[14]) & ~err_found;
+ en_buf[14] = (sysen_s2 & delay_done[13]) & ~err_found;
+ end
// ERR state reset
- assign clear_err = i2c_clr_err;
+ always @(posedge clk_in) begin
+ clear_err = i2c_clr_err;
+ end
// CPUB clk enables
- assign cpub_clk_oea = ~cpub_present_n;
- assign cpub_clk_oeb = ~cpub_present_n;
+ always @(posedge clk_in) begin
+ cpub_clk_oea = ~cpub_present_n;
+ cpub_clk_oeb = ~cpub_present_n;
+ end
// System PWRGOOD
- assign sysgood_buf = delay_done[14];
- assign sysgood = sysgood_buf & bmc_software_pg;
- assign lpc_rst = sysgood_buf;
+ always @(posedge clk_in) begin
+ sysgood_buf = delay_done[14];
+ sysgood = sysgood_buf & bmc_software_pg;
+ lpc_rst = sysgood_buf;
+ end
// CPU Reset
- assign cpu_stby_rst = en_buf[0];
+ always @(posedge clk_in) begin
+ cpu_stby_rst = en_buf[0];
+ end
// BMC RESETs
- assign bmc_rst = bmc_vr_pg;
- assign usbhub_rst = sysgood_buf & bmc_software_pg;
- assign fan_rst = ~bmc_vr_pg;
+ always @(posedge clk_in) begin
+ bmc_rst = bmc_vr_pg;
+ usbhub_rst = sysgood_buf & bmc_software_pg;
+ fan_rst = ~bmc_vr_pg;
+ end
// debug_in override allows non-BMC control of FPGA
- assign sysen_buf = sysen | ~debug_in;
- // assign sysen_buf = ~debug_in;
+ always @(posedge clk_in) begin
+ sysen_buf = sysen | ~debug_in;
+ // sysen_buf = ~debug_in;
+ end
// Enable V5_0_DUAL rail
- assign dual_5v_ctrl = 1'b0;
+ always @(posedge clk_in) begin
+ dual_5v_ctrl = 1'b0;
+ end
// Enable PMC
- assign pmc_disable_n = 1'b1;
+ always @(posedge clk_in) begin
+ pmc_disable_n = 1'b1;
+ end
// Not used
- assign window_open_n = 1'b0;
+ always @(posedge clk_in) begin
+ window_open_n = 1'b0;
+ end
// Generate standard front panel NIC activity indications
- assign panel_nic1_led_cathode_std = (nic1_link_led_n & nic1_green_led_n) & ~nic1_act_led_n;
- assign panel_nic2_led_cathode_std = (nic2_link_led_n & nic2_green_led_n) & ~nic2_act_led_n;
+ always @(posedge clk_in) begin
+ panel_nic1_led_cathode_std = (nic1_link_led_n & nic1_green_led_n) & ~nic1_act_led_n;
+ panel_nic2_led_cathode_std = (nic2_link_led_n & nic2_green_led_n) & ~nic2_act_led_n;
+ end
// Wire up UID request to front panel
- assign panel_uid_led_std = bmc_uid_led_req;
+ always @(posedge clk_in) begin
+ panel_uid_led_std = bmc_uid_led_req;
+ end
// Assign front panel indicators according to BMC status
assign panel_nic1_led_cathode = (bmc_software_pg)?panel_nic1_led_cathode_std:bmc_startup_kr[0];
@@ -660,7 +721,9 @@ module system_fpga_top
assign panel_uid_led = (bmc_software_pg)?panel_uid_led_std:bmc_startup_kr[2];
// Generate master reset request signals
- assign master_reset_reqest = ~(panel_reset_in_l & flexver_reset_in_l);
- assign bmc_system_reset_request_n = ~master_reset_reqest;
+ always @(posedge clk_in) begin
+ master_reset_reqest = ~(panel_reset_in_l & flexver_reset_in_l);
+ bmc_system_reset_request_n = ~master_reset_reqest;
+ end
endmodule
diff --git a/system_fpga.pcf b/system_fpga.pcf
index 89976b9..ce653c6 100644
--- a/system_fpga.pcf
+++ b/system_fpga.pcf
@@ -1,9 +1,29 @@
# This file is part of the Talos™ II system FPGA implementation
#
-# © 2017 Raptor Engineering, LLC
+# © 2017 - 2018 Raptor Engineering, LLC
# All Rights Reserved
#
-# Licensed for exclusive use with Talos™ II systems from Raptor Computing Systems
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer: 2) Redistributions in binary
+# form must reproduce the above copyright notice, this list of conditions and the
+# following disclaimer in the documentation and/or other materials provided with the
+# distribution, and; 3) Neither the name of Raptor Engineering, LLC, nor the names of its
+# contributors may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS,
+# STATUTORY OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Intended for use with Talos™ II systems from Raptor Computing Systems, LLC
# https://www.raptorcs.com/TALOSII
# LPC clock
OpenPOWER on IntegriCloud