summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaptor Engineering Development Team <support@raptorengineering.com>2017-12-30 17:50:01 -0600
committerRaptor Engineering Development Team <support@raptorengineering.com>2017-12-30 17:50:01 -0600
commit0b1c5059e5655f31a3d9c229ea5821ece9aee052 (patch)
treed372e4c673f97acebdc3b4eaf46711da2d872fe9
parent7cf24ce07484a6d86cd97a9af9c240da7e1a4043 (diff)
downloadtalos-system-fpga-0b1c5059e5655f31a3d9c229ea5821ece9aee052.tar.gz
talos-system-fpga-0b1c5059e5655f31a3d9c229ea5821ece9aee052.zip
Initial buildable variant for Talos™ II
-rw-r--r--Makefile105
-rw-r--r--i2c_slave.v50
-rw-r--r--main.v558
-rw-r--r--power_sequencer.v (renamed from pwrseq.v)143
-rw-r--r--system_fpga.pcf76
-rw-r--r--top.v536
6 files changed, 847 insertions, 621 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ebfddd3
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,105 @@
+# This file is part of the Talos™ II system FPGA implementation
+#
+# © 2017 Raptor Engineering, LLC
+# All Rights Reserved
+#
+# Licensed for exclusive use with Talos™ II systems from Raptor Computing Systems
+# https://www.raptorcs.com/TALOSII
+
+MAX_FPGA_ROUTE_PASSES = 100
+
+# Default seed
+#ARACHNE_PNR_SEED = 1
+
+# Selected seed from fastest placement search
+# NOTE: Must be updated every time the Verilog source is modified, no matter how trivially!
+# Does not need to be updated if firmware program (C) sources are modified
+# 0 automatically uses the best placement result
+ARACHNE_PNR_SEED = 0
+#ARACHNE_PNR_SEED = 1
+
+YOSYS_ICE40_SIM_LIB = $(shell yosys-config --datdir/ice40/cells_sim.v)
+
+.PRECIOUS: system_fpga_%.int
+
+system_fpga_%.tmg: system_fpga_%.int
+ echo "Total path delay: inf ns (0.0 MHz)" > $@
+ -icetime -tmd hx1k -p system_fpga.pcf -P vq100 $< > $@ 2>&1
+
+system_fpga_%.int: system_fpga.blif
+ echo "" > $@
+ -arachne-pnr -s $* -d 1k -P vq100 -m $(MAX_FPGA_ROUTE_PASSES) -p system_fpga.pcf $< -o $@
+
+system_fpga.int: system_fpga_1.tmg system_fpga_2.tmg system_fpga_3.tmg system_fpga_4.tmg system_fpga_5.tmg system_fpga_6.tmg system_fpga_7.tmg system_fpga_8.tmg system_fpga_9.tmg \
+ system_fpga_10.tmg system_fpga_11.tmg system_fpga_12.tmg system_fpga_13.tmg system_fpga_14.tmg system_fpga_15.tmg system_fpga_16.tmg system_fpga_17.tmg system_fpga_18.tmg system_fpga_19.tmg \
+ system_fpga_20.tmg system_fpga_21.tmg system_fpga_22.tmg system_fpga_23.tmg system_fpga_24.tmg system_fpga_25.tmg system_fpga_26.tmg system_fpga_27.tmg system_fpga_28.tmg system_fpga_29.tmg \
+ system_fpga_30.tmg system_fpga_31.tmg system_fpga_32.tmg system_fpga_33.tmg system_fpga_34.tmg system_fpga_35.tmg system_fpga_36.tmg system_fpga_37.tmg system_fpga_38.tmg system_fpga_39.tmg \
+ system_fpga_40.tmg system_fpga_41.tmg system_fpga_42.tmg system_fpga_43.tmg system_fpga_44.tmg system_fpga_45.tmg system_fpga_46.tmg system_fpga_47.tmg system_fpga_48.tmg system_fpga_49.tmg \
+ system_fpga_50.tmg system_fpga_51.tmg system_fpga_52.tmg system_fpga_53.tmg system_fpga_54.tmg system_fpga_55.tmg system_fpga_56.tmg system_fpga_57.tmg system_fpga_58.tmg system_fpga_59.tmg \
+ system_fpga_60.tmg system_fpga_61.tmg system_fpga_62.tmg system_fpga_63.tmg system_fpga_64.tmg
+ BEST_TRIAL=0; \
+ BEST_TRIAL_RESULT=0; \
+ 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"; \
+ COMPARISON_RESULT=$$(echo "$$CURRENT_TRIAL_RESULT > $$BEST_TRIAL_RESULT" | bc -l); \
+ if [ $$COMPARISON_RESULT -eq 1 ]; then \
+ BEST_TRIAL=system_fpga_$${trial}.tmg; \
+ BEST_TRIAL_RESULT=$$CURRENT_TRIAL_RESULT; \
+ fi; \
+ fi; \
+ done; \
+ 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
+ifneq ($(ARACHNE_PNR_SEED),0)
+ cp system_fpga_$(ARACHNE_PNR_SEED).int system_fpga.int
+ cp system_fpga_$(ARACHNE_PNR_SEED).tmg system_fpga.tmg
+endif
+ cat system_fpga.tmg
+
+system_fpga.ex: system_fpga.int
+ icebox_explain system_fpga.int > system_fpga.ex
+
+system_fpga.blif: main.v power_sequencer.v i2c_slave.v
+ yosys -l yosys.log -q -p "synth_ice40 -top system_fpga_top -blif system_fpga.blif" main.v power_sequencer.v i2c_slave.v
+
+system_fpga.bin: system_fpga.int
+ cp system_fpga.int system_fpga.bin
+
+blank.rom:
+ dd if=/dev/zero ibs=1M count=4 | tr "\000" "\377" > blank.rom
+
+system_fpga.rom: blank.rom system_fpga.bin
+ cp blank.rom system_fpga.rom
+ dd if=system_fpga.bin of=system_fpga.rom conv=notrunc
+
+all: system_fpga.rom
+
+dump_toolchain_info:
+ -@echo "================================================================================"
+ -@echo "Base system:\t"
+ -@echo -n "Architecture:\t"
+ -@uname -m 2>/dev/null
+ -@echo -n "gcc:\t\t"
+ -@gcc -dumpversion 2>/dev/null
+ -@echo -n "clang:\t\t"
+ -@clang --version 2>/dev/null | head -n 1
+ -@echo "\nFPGA toolchain:"
+ -@echo -n "Icarus verilog:\t"
+ -@iverilog -V 2>/dev/null | head -n 1
+ -@echo -n "Yosys:\t\t"
+ -@yosys -V 2>/dev/null
+ -@echo -n "arachne-pnr:\t"
+ -@arachne-pnr -v 2>/dev/null
+ -@echo "================================================================================"
+
+test: system_fpga.bin
+ iceprog -S system_fpga.bin
+
+flash: system_fpga.bin
+ iceprog system_fpga.bin
+
+clean:
+ rm -f system_fpga.blif system_fpga.ex system_fpga.int system_fpga.tmg system_fpga_*.int system_fpga_*.tmg system_fpga.bin yosys.log
diff --git a/i2c_slave.v b/i2c_slave.v
index 2701ef4..14c97f6 100644
--- a/i2c_slave.v
+++ b/i2c_slave.v
@@ -1,12 +1,18 @@
-// Copyright © 2017 Raptor Engineering, LLC
// Copyright © 2014-2016 Peter Samarin
+// Copyright © 2017 Raptor Engineering, LLC
// All Rights Reserved
//
// See I2C_SLAVE_LICENSE file for licensing details
-module I2C_slave(
- inout wire scl,
- inout wire sda,
+module i2c_slave(
+ input wire scl_in,
+ output wire scl_out,
+ output wire scl_direction,
+
+ input wire sda_in,
+ output wire sda_out,
+ output wire sda_direction,
+
input wire clk,
input wire rst,
@@ -17,7 +23,7 @@ module I2C_slave(
output wire [7:0] data_from_master
);
- parameter [6:0] SLAVE_ADDR;
+ parameter [6:0] SLAVE_ADDR = 0;
//----------------------------------------------------------
@@ -34,32 +40,32 @@ module I2C_slave(
reg [2:0] state_reg = i2c_idle;
reg cmd_reg = 1'b0;
reg [31:0] bits_processed_reg = 0;
- reg continue_reg = 1'b0; // Helpers to figure out next state
+ reg continue_reg = 1'b0; // Helpers to figure out next state
reg start_reg = 1'b0;
reg stop_reg = 1'b0;
reg scl_rising_reg = 1'b0;
- reg scl_falling_reg = 1'b0; // Address and data received from master
+ reg scl_falling_reg = 1'b0; // Address and data received from master
reg [6:0] addr_reg = 1'b0;
- reg [7:0] data_reg = 1'b0; // Delayed SCL (by 1 clock cycle, and by 2 clock cycles)
+ reg [7:0] data_reg = 1'b0; // Delayed SCL (by 1 clock cycle, and by 2 clock cycles)
reg scl_reg = 1'b1;
- reg scl_prev_reg = 1'b1; // Slave writes on scl
+ reg scl_prev_reg = 1'b1; // Slave writes on scl
wire scl_wen_reg = 1'b0;
- wire scl_o_reg = 1'b0; // Delayed SDA (1 clock cycle, and 2 clock cycles)
+ wire scl_o_reg = 1'b0; // Delayed SDA (1 clock cycle, and 2 clock cycles)
reg sda_reg = 1'b1;
- reg sda_prev_reg = 1'b1; // Slave writes on sda
+ reg sda_prev_reg = 1'b1; // Slave writes on sda
reg sda_wen_reg = 1'b0;
- reg sda_o_reg = 1'b0; // User interface
+ reg sda_o_reg = 1'b0; // User interface
reg data_valid_reg = 1'b0;
reg read_req_reg = 1'b0;
reg [7:0] data_to_master_reg = 1'b0;
always @(posedge clk) begin
// Delay SCL by 1 and 2 clock cycles
- scl_reg <= scl;
+ scl_reg <= scl_in;
scl_prev_reg <= scl_reg;
// Delay SDA by 1 and 2 clock cycles
- sda_reg <= sda;
+ sda_reg <= sda_in;
sda_prev_reg <= sda_reg;
// Detect rising and falling SCL
@@ -223,23 +229,25 @@ module I2C_slave(
// Reset counter and state on start/stop
//------------------------------------------------------
if (start_reg == 1'b1) begin
- state_reg <= i2c_get_address_and_cmd;
- bits_processed_reg <= 0;
+ state_reg <= i2c_get_address_and_cmd;
+ bits_processed_reg <= 0;
end
if (stop_reg == 1'b1) begin
- state_reg <= i2c_idle;
- bits_processed_reg <= 0;
+ state_reg <= i2c_idle;
+ bits_processed_reg <= 0;
end
if (rst == 1'b1) begin
- state_reg <= i2c_idle;
+ state_reg <= i2c_idle;
end
end
//--------------------------------------------------------
// I2C interface
//--------------------------------------------------------
- assign sda = sda_wen_reg == 1'b1 ? sda_o_reg : 1'bZ;
- assign scl = scl_wen_reg == 1'b1 ? scl_o_reg : 1'bZ;
+ assign sda_out = (sda_o_reg & sda_wen_reg);
+ assign sda_direction = sda_wen_reg;
+ assign scl_out = (scl_o_reg & scl_wen_reg);
+ assign scl_direction = scl_wen_reg;
//--------------------------------------------------------
// User interface
//--------------------------------------------------------
diff --git a/main.v b/main.v
new file mode 100644
index 0000000..3b85894
--- /dev/null
+++ b/main.v
@@ -0,0 +1,558 @@
+// Copyright © 2017, International Business Machines Corp.
+// Copyright © 2017 Raptor Engineering, LLC
+// All Rights Reserved
+//
+// See LICENSE file for licensing details
+
+module system_fpga_top
+ (
+ // LPC clock
+ input wire lpc_clock,
+
+ // General I/O
+ input wire sysen,
+ output wire 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,
+
+ // Power Good inputs
+ input wire vdda_pg,
+ input wire vddb_pg,
+ input wire vcsa_pg,
+ input wire vcsb_pg,
+ input wire vdna_pg,
+ input wire vdnb_pg,
+ input wire vioa_pg,
+ input wire viob_pg,
+ input wire vppab_pg,
+ input wire vppcd_pg,
+ input wire vddrab_pg,
+ input wire vddrcd_pg,
+ input wire avdd_pg,
+ input wire miscio_pg,
+ input wire atx_pg,
+ input wire bmc_vr_pg,
+
+ // I2C
+ inout i2c_scl,
+ inout i2c_sda,
+
+ // Second CPU Present Detection
+ input wire cpub_present_n,
+ output wire cpub_clk_oea,
+ output wire cpub_clk_oeb,
+
+ // Resets
+ output wire lpc_rst,
+ input wire bmc_software_pg,
+ output wire bmc_rst,
+ output wire fan_rst,
+ output wire usbhub_rst,
+ output wire cpu_stby_rst,
+
+ // Reserved for Future Use
+ output wire dual_5v_ctrl,
+ output wire window_open_n
+ );
+
+ wire i2c_scl_in;
+ wire i2c_scl_out;
+ wire i2c_scl_direction;
+
+ wire i2c_sda_in;
+ wire i2c_sda_out;
+ wire i2c_sda_direction;
+
+ SB_IO #(
+ .PIN_TYPE(6'b101001),
+ .PULLUP(1'b1)
+ ) i2c_scl_io (
+ .PACKAGE_PIN(i2c_scl),
+ .OUTPUT_ENABLE(i2c_scl_direction),
+ .D_OUT_0(i2c_scl_out),
+ .D_IN_0(i2c_scl_in)
+ );
+
+ SB_IO #(
+ .PIN_TYPE(6'b101001),
+ .PULLUP(1'b1)
+ ) i2c_sda_io (
+ .PACKAGE_PIN(i2c_sda),
+ .OUTPUT_ENABLE(i2c_sda_direction),
+ .D_OUT_0(i2c_sda_out),
+ .D_IN_0(i2c_sda_in)
+ );
+
+ // TODO update version
+ parameter fpga_version = 8'b00000110;
+ parameter rail_size = 15;
+ wire [rail_size - 1:0] en_buf = 1'b0;
+ wire [rail_size - 1:0] pg_buf;
+ wire sysgood_buf;
+ wire clk_in;
+ 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_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
+ // 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;
+ reg err_found = 1'b0;
+ wire clear_err = 1'b0;
+
+ // i2c signals
+ wire i2c_read_req;
+ reg [7:0] i2c_data_to_master = 8'b00000000;
+ wire [7:0] i2c_data_from_master;
+ wire i2c_data_valid;
+ wire i2c_rst = 1'b0;
+ reg [7:0] i2c_reg_cur = 8'b00000000;
+ parameter i2c_addr = 7'b0110001;
+ parameter i2c_clr_err_addr = 8'b00000011;
+ parameter i2c_pg_reg_addr1 = 8'b00000101;
+ parameter i2c_pg_reg_addr2 = i2c_pg_reg_addr1 + 1;
+ parameter i2c_status_reg_addr = i2c_pg_reg_addr2 + 1;
+ parameter i2c_version_reg_addr = 8'b00000000;
+ reg [15:0] i2c_pg_reg = 1'b0;
+ reg i2c_clr_err = 1'b0;
+
+ // Divide input 33MHz clock down to 4.125MHz
+ reg [2:0] clock_divider;
+ always @(posedge lpc_clock) begin
+ clock_divider = clock_divider + 1;
+ end
+ assign clk_in = clock_divider[2];
+
+ // I2C device
+ i2c_slave #(
+ .SLAVE_ADDR(i2c_addr)
+ )
+ i2c_slave_instance(
+ .scl_in(i2c_scl_in),
+ .scl_out(i2c_scl_out),
+ .scl_direction(i2c_scl_direction),
+
+ .sda_in(i2c_sda_in),
+ .sda_out(i2c_sda_out),
+ .sda_direction(i2c_sda_direction),
+
+ .clk(clk_in),
+ .rst(i2c_rst),
+ .read_req(i2c_read_req),
+ .data_to_master(i2c_data_to_master),
+ .data_valid(i2c_data_valid),
+ .data_from_master(i2c_data_from_master)
+ );
+
+ assign i2c_rst = 1'b0;
+ // Handle I2C
+ // 2 8-bit registers with PGOOD state on error
+ always @(posedge clk_in) begin
+ i2c_clr_err <= 1'b0;
+
+ if (i2c_data_valid == 1'b1) begin
+ // data from master is register to be read
+ i2c_reg_cur <= i2c_data_from_master;
+
+ //pulse clear err signal if i2c master reads register 0x03
+ if (((i2c_data_from_master) == i2c_clr_err_addr)) begin
+ i2c_clr_err <= 1'b1;
+ end
+ end
+ else if (i2c_read_req == 1'b1) begin
+ i2c_reg_cur <= i2c_reg_cur + 1;
+ end
+ case(i2c_reg_cur)
+ i2c_clr_err_addr : begin
+ i2c_data_to_master <= 8'b11111111;
+ end
+ i2c_pg_reg_addr1 : begin
+ i2c_data_to_master <= i2c_pg_reg[15:8];
+ end
+ i2c_pg_reg_addr2 : begin
+ i2c_data_to_master <= i2c_pg_reg[7:0];
+ end
+ i2c_status_reg_addr : begin
+ // TODO add CPU1 presence detect
+ i2c_data_to_master <= {3'b000, wait_err, operation_err, err_found, sysen_buf, sysgood_buf};
+ end
+ i2c_version_reg_addr : begin
+ i2c_data_to_master <= fpga_version;
+ end
+ default : begin
+ i2c_data_to_master <= 8'b00000000;
+ end
+ endcase
+ end
+
+ always @(posedge clk_in) begin
+ pg_s1 <= pg_buf;
+ pg_s2 <= pg_s1;
+ sysen_s1 <= sysen_buf;
+ sysen_s2 <= sysen_s1;
+ seq_s1 <= seq_cont;
+ seq_s2 <= seq_s1;
+ if ((clear_err == 1'b1)) begin
+ wait_err <= 1'b0;
+ operation_err <= 1'b0;
+ err_found <= 1'b0;
+ w_count <= {24{1'b0}};
+ d_count <= {17{1'b0}};
+ end
+ 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}};
+ end
+ else if ((pg_s2[0] == 1'b1 && en_buf[0] == 1'b1 && delay_done[0] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[0] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[1] == 1'b1 && en_buf[1] == 1'b1 && delay_done[1] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[1] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[2] == 1'b1 && en_buf[2] == 1'b1 && delay_done[2] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[2] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[3] == 1'b1 && en_buf[3] == 1'b1 && delay_done[3] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[3] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[4] == 1'b1 && en_buf[4] == 1'b1 && delay_done[4] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[4] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[5] == 1'b1 && en_buf[5] == 1'b1 && delay_done[5] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[5] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[6] == 1'b1 && en_buf[6] == 1'b1 && delay_done[6] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[6] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[7] == 1'b1 && en_buf[7] == 1'b1 && delay_done[7] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[7] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[8] == 1'b1 && en_buf[8] == 1'b1 && delay_done[8] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[8] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[9] == 1'b1 && en_buf[9] == 1'b1 && delay_done[9] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[9] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[10] == 1'b1 && en_buf[10] == 1'b1 && delay_done[10] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[10] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[11] == 1'b1 && en_buf[11] == 1'b1 && delay_done[11] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[11] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[12] == 1'b1 && en_buf[12] == 1'b1 && delay_done[12] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[12] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[13] == 1'b1 && en_buf[13] == 1'b1 && delay_done[13] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[13] <= 1'b1;
+ end
+ end
+ else if ((pg_s2[14] == 1'b1 && en_buf[14] == 1'b1 && delay_done[14] == 1'b0)) begin
+ w_count <= {24{1'b0}};
+ d_count <= d_count + 1;
+ if ((d_count[16] == 1'b1)) begin
+ d_count <= {17{1'b0}};
+ delay_done[14] <= 1'b1;
+ end
+ end
+
+ // Error Checks
+ // Check time between Enables going high and PGOODs arriving. Error out after 100ms
+ else if ((pg_s2[0] == 1'b0 && en_buf[0] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[1] == 1'b0 && en_buf[1] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[2] == 1'b0 && en_buf[2] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[3] == 1'b0 && en_buf[3] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[4] == 1'b0 && en_buf[4] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[5] == 1'b0 && en_buf[5] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[6] == 1'b0 && en_buf[6] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[7] == 1'b0 && en_buf[7] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[8] == 1'b0 && en_buf[8] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[9] == 1'b0 && en_buf[9] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[10] == 1'b0 && en_buf[10] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[11] == 1'b0 && en_buf[11] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[12] == 1'b0 && en_buf[12] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[13] == 1'b0 && en_buf[13] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ else if ((pg_s2[14] == 1'b0 && en_buf[14] == 1'b1)) begin
+ w_count <= w_count + 1;
+ if ((w_count[23] == 1'b1)) begin
+ w_count <= {24{1'b0}};
+ wait_err <= 1'b1;
+ end
+ end
+ if ((( ~(delay_done & ~pg_s2)) != railarray_1)) begin
+ operation_err <= 1'b1;
+ end
+ if (((wait_err | operation_err) == 1'b1 && clear_err == 1'b0)) begin
+ err_found <= 1'b1;
+ end else begin
+ i2c_pg_reg[14:0] <= pg_s2[14:0];
+ end
+ 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;
+
+ // 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]);
+
+ // 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;
+
+ // ERR state reset
+ assign clear_err = i2c_clr_err;
+
+ // CPUB clk enables
+ assign cpub_clk_oea = ~cpub_present_n;
+ assign cpub_clk_oeb = ~cpub_present_n;
+
+ // System PWRGOOD
+ assign sysgood_buf = delay_done[14];
+ assign sysgood = sysgood_buf & bmc_software_pg;
+ assign lpc_rst = sysgood_buf;
+
+ // CPU Reset
+ assign cpu_stby_rst = en_buf[0];
+
+ // BMC RESETs
+ assign bmc_rst = bmc_vr_pg;
+ assign usbhub_rst = sysgood_buf & bmc_software_pg;
+ assign fan_rst = ~bmc_vr_pg;
+
+ // debug_in override allows non-BMC control of CPLD
+ assign sysen_buf = sysen | ~debug_in;
+ // assign sysen_buf = ~debug_in;
+
+ assign dual_5v_ctrl = 1'b0;
+ assign window_open_n = 1'b0;
+
+endmodule
diff --git a/pwrseq.v b/power_sequencer.v
index c4f9f5a..d099cbf 100644
--- a/pwrseq.v
+++ b/power_sequencer.v
@@ -1,28 +1,35 @@
-// Copyright © 2017 Raptor Engineering, LLC
// Copyright © 2017, International Business Machines Corp.
+// Copyright © 2017 Raptor Engineering, LLC
// All Rights Reserved
//
// See LICENSE file for licensing details
module pwrseq(
- output wire [rail_size - 1:0] EN,
- input wire [rail_size - 1:0] PGOOD_A,
- input wire SYSEN_A,
- output wire SYSGOOD,
- inout wire SCL,
- inout wire SDA,
- input wire CLK_IN
+ output wire [rail_size - 1:0] en,
+ input wire [rail_size - 1:0] pgood_a,
+ input wire sysen_a,
+ output wire sysgood,
+
+ input wire scl_in,
+ output wire scl_out,
+ output wire scl_direction,
+
+ input wire sda_in,
+ output wire sda_out,
+ output wire sda_direction,
+
+ input wire clk_in
);
- parameter [31:0] rail_size;
+ parameter [31:0] rail_size = 15;
// Input output buffers and synchronizers
- reg [rail_size - 1:0] EN_BUF = 1'b0;
- reg [rail_size - 1:0] PGOOD = 1'b0;
- reg [rail_size - 1:0] PGOOD_S = 1'b0;
- reg SYSEN = 1'b0;
- reg SYSEN_S = 1'b0;
- reg SYSGOOD_BUF = 1'b0;
+ reg [rail_size - 1:0] en_buf = 1'b0;
+ reg [rail_size - 1:0] pgood = 1'b0;
+ reg [rail_size - 1:0] pgood_s = 1'b0;
+ reg sysen = 1'b0;
+ reg sysen_s = 1'b0;
+ reg sysgood_buf = 1'b0;
// Sequencer State Machine
parameter [2:0] idleon = 0;
@@ -34,14 +41,14 @@ module pwrseq(
parameter [2:0] waitoff = 6;
reg [2:0] state = idleoff;
- reg ERR = 1'b0;
+ reg err = 1'b0;
reg [15:0] err_msg = 1'b1;
parameter all_on = 1'b1;
parameter all_off = 1'b0;
// Clocks and timers
parameter counter_size = 20;
- reg [counter_size - 1:0] T_COUNT;
+ reg [counter_size - 1:0] t_count;
// t_max_wait is max delay from Enable assert to Pgood assert (200 ms assumption 4.125MHz clk)
parameter t_max_wait = 825000;
@@ -61,21 +68,29 @@ module pwrseq(
parameter i2c_pg_reg_addr2 = i2c_pg_reg_addr1 + 1;
parameter i2c_status_reg_addr = i2c_pg_reg_addr2 + 1;
- I2C_slave #(i2c_addr)
- I2C_SLAVE(
- SCL,
- SDA,
- CLK_IN,
- i2c_rst,
- i2c_read_req,
- i2c_data_to_master,
- i2c_data_valid,
- i2c_data_from_master
+ i2c_slave #(
+ .SLAVE_ADDR(i2c_addr)
+ )
+ i2c_slave_instance(
+ .scl_in(scl_in),
+ .scl_out(scl_out),
+ .scl_direction(scl_direction),
+
+ .sda_in(sda_in),
+ .sda_out(sda_out),
+ .sda_direction(sda_direction),
+
+ .clk(clk_in),
+ .rst(i2c_rst),
+ .read_req(i2c_read_req),
+ .data_to_master(i2c_data_to_master),
+ .data_valid(i2c_data_valid),
+ .data_from_master(i2c_data_from_master)
);
// Handle I2C
- // 2 8-bit registers with PGOOD state on error
- always @(posedge CLK_IN) begin
+ // 2 8-bit registers with pgood state on error
+ always @(posedge clk_in) begin
//return high byte with any memory address, loop on any consecutive reads
if (i2c_data_valid == 1'b1) begin
i2c_reg_cur <= i2c_data_from_master;
@@ -91,7 +106,7 @@ module pwrseq(
i2c_data_to_master <= err_msg[7:0];
end
i2c_status_reg_addr : begin
- i2c_data_to_master <= {6'b000000,SYSEN,SYSGOOD_BUF};
+ i2c_data_to_master <= {6'b000000, sysen, sysgood_buf};
end
default : begin
i2c_data_to_master <= 8'b00000000;
@@ -100,24 +115,24 @@ module pwrseq(
end
// Power Sequencer state machine
- always @(posedge CLK_IN) begin
+ always @(posedge clk_in) begin
// Increase counter
- T_COUNT <= T_COUNT + 1;
+ t_count <= t_count + 1;
// Synchronize Asynchronous inputs to clock
- PGOOD_S <= PGOOD_A;
- PGOOD <= PGOOD_S;
- SYSEN_S <= SYSEN_A;
- SYSEN <= SYSEN_S;
+ pgood_s <= pgood_a;
+ pgood <= pgood_s;
+ sysen_s <= sysen_a;
+ sysen <= sysen_s;
// Decide next state
case(state)
idleoff : begin
//Only leave idle off if system enable active and no error
- if (ERR == 1'b1) begin
+ if (err == 1'b1) begin
state <= idleoff;
end
- else if (SYSEN == 1'b1) begin
+ else if (sysen == 1'b1) begin
state <= shifton;
end else begin
state <= idleoff;
@@ -125,24 +140,24 @@ module pwrseq(
end
shifton : begin
// enable next power rail, reset counter, wait for pgood
- EN_BUF[rail_size - 1:1] <= EN_BUF[rail_size - 2:0];
- EN_BUF[0] <= 1'b1;
- T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}};
+ en_buf[rail_size - 1:1] <= en_buf[rail_size - 2:0];
+ en_buf[0] <= 1'b1;
+ t_count <= {(((counter_size - 1))-((0))+1){1'b0}};
state <= waitpgood;
end
waitpgood : begin
- // Wait for enabled power rail's PGOOD, after time with no pgood, error
- if (T_COUNT > t_max_wait) begin
- ERR <= 1'b1;
+ // Wait for enabled power rail's pgood, after time with no pgood, error
+ if (t_count > t_max_wait) begin
+ err <= 1'b1;
err_msg <= {16{1'b0}};
- err_msg[rail_size - 1:0] <= EN_BUF & PGOOD;
+ err_msg[rail_size - 1:0] <= en_buf & pgood;
state <= shiftoff;
end
- else if ((EN_BUF & PGOOD) == all_on) begin
+ else if ((en_buf & pgood) == all_on) begin
state <= idleon;
end
- else if (((EN_BUF & PGOOD) == EN_BUF)) begin
- T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}};
+ else if (((en_buf & pgood) == en_buf)) begin
+ t_count <= {(((counter_size - 1))-((0))+1){1'b0}};
state <= waiten;
end else begin
state <= waitpgood;
@@ -150,8 +165,8 @@ module pwrseq(
end
waiten : begin
// delay between last pgood and next enable
- if (T_COUNT > t_delay) begin
- T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}};
+ if (t_count > t_delay) begin
+ t_count <= {(((counter_size - 1))-((0))+1){1'b0}};
state <= shifton;
end else begin
state <= waiten;
@@ -159,14 +174,14 @@ module pwrseq(
end
idleon : begin
// stay in idle on unless power rail goes down (error) or system enable removed
- SYSGOOD_BUF <= 1'b1;
- if ((!(PGOOD == all_on))) begin
- ERR <= 1'b1;
+ sysgood_buf <= 1'b1;
+ if ((!(pgood == all_on))) begin
+ err <= 1'b1;
err_msg <= {16{1'b0}};
- err_msg[rail_size - 1:0] <= PGOOD;
+ err_msg[rail_size - 1:0] <= pgood;
end
- if (((SYSEN == 1'b0) || (ERR == 1'b1))) begin
- SYSGOOD_BUF <= 1'b0;
+ if (((sysen == 1'b0) || (err == 1'b1))) begin
+ sysgood_buf <= 1'b0;
state <= shiftoff;
end else begin
state <= idleon;
@@ -174,22 +189,22 @@ module pwrseq(
end
shiftoff : begin
// Turn off enable for next power rail
- EN_BUF[rail_size - 2:0] <= EN_BUF[rail_size - 1:1];
- EN_BUF[rail_size - 1] <= 1'b0;
- if ((EN_BUF == all_off)) begin
+ en_buf[rail_size - 2:0] <= en_buf[rail_size - 1:1];
+ en_buf[rail_size - 1] <= 1'b0;
+ if ((en_buf == all_off)) begin
state <= idleoff;
end else begin
- T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}};
+ t_count <= {(((counter_size - 1))-((0))+1){1'b0}};
state <= waitoff;
end
end
waitoff : begin
// in controlled shutdown, delay between disabling power rails
- if (ERR == 1'b1) begin
+ if (err == 1'b1) begin
state <= shiftoff;
//LED_BUF <= "10";
end
- else if (T_COUNT > t_delay) begin
+ else if (t_count > t_delay) begin
state <= shiftoff;
//LED_BUF <= "10";
end else begin
@@ -200,8 +215,8 @@ module pwrseq(
end
// Output enable buffer to pins
- assign EN = ~(EN_BUF);
+ assign en = ~(en_buf);
assign i2c_rst = 1'b0;
- assign SYSGOOD = SYSGOOD_BUF;
+ assign sysgood = sysgood_buf;
endmodule \ No newline at end of file
diff --git a/system_fpga.pcf b/system_fpga.pcf
new file mode 100644
index 0000000..51ecc68
--- /dev/null
+++ b/system_fpga.pcf
@@ -0,0 +1,76 @@
+# This file is part of the Talos™ II system FPGA implementation
+#
+# © 2017 Raptor Engineering, LLC
+# All Rights Reserved
+#
+# Licensed for exclusive use with Talos™ II systems from Raptor Computing Systems
+# https://www.raptorcs.com/TALOSII
+
+# LPC clock
+set_io lpc_clock 13
+
+# General I/O
+set_io sysen 15
+set_io sysgood 53
+set_io debug_in 25
+
+# Workaround Control
+set_io seq_cont 100
+
+# Power Plane Enable
+set_io vdda_en 72
+set_io vddb_en 79
+set_io vcsa_en 71
+set_io vcsb_en 78
+set_io vdna_en 68
+set_io vdnb_en 51
+set_io vioa_en 66
+set_io viob_en 69
+set_io vppab_en 52
+set_io vppcd_en 60
+set_io vddrab_en 65
+set_io vttab_en 62
+set_io vddrcd_en 64
+set_io vttcd_en 63
+set_io avdd_en 59
+set_io miscio_en 56
+set_io atx_en 57
+
+# Power Good Sense
+set_io vdda_pg 28
+set_io vddb_pg 26
+set_io vcsa_pg 29
+set_io vcsb_pg 27
+set_io vdna_pg 34
+set_io vdnb_pg 30
+set_io vioa_pg 36
+set_io viob_pg 33
+set_io vppab_pg 42
+set_io vppcd_pg 41
+set_io vddrab_pg 37
+set_io vddrcd_pg 40
+set_io avdd_pg 19
+set_io miscio_pg 24
+set_io atx_pg 20
+set_io bmc_vr_pg 18
+
+# I2C
+set_io i2c_scl 86
+set_io i2c_sda 85
+
+# CPU B Presence Detect
+set_io cpub_present_n 4
+set_io cpub_clk_oea 10
+set_io cpub_clk_oeb 9
+
+# Resets
+set_io lpc_rst 82
+set_io bmc_software_pg 8
+set_io bmc_rst 83
+set_io fan_rst 1
+set_io usbhub_rst 87
+set_io cpu_stby_rst 54
+
+# Reserved
+set_io dual_5v_ctrl 80
+set_io window_open_n 99 \ No newline at end of file
diff --git a/top.v b/top.v
deleted file mode 100644
index a107dda..0000000
--- a/top.v
+++ /dev/null
@@ -1,536 +0,0 @@
-// Copyright © 2017 Raptor Engineering, LLC
-// Copyright © 2017, International Business Machines Corp.
-// All Rights Reserved
-//
-// See LICENSE file for licensing details
-
-module FPGA_TOP
- (
- // General I/O
- input wire SYSEN,
- output wire 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,
-
- // Power Good inputs
- input wire VDDA_PG,
- input wire VDDB_PG,
- input wire VCSA_PG,
- input wire VCSB_PG,
- input wire VDNA_PG,
- input wire VDNB_PG,
- input wire VIOA_PG,
- input wire VIOB_PG,
- input wire VPPAB_PG,
- input wire VPPCD_PG,
- input wire VDDRAB_PG,
- input wire VDDRCD_PG,
- input wire AVDD_PG,
- input wire MISCIO_PG,
- input wire ATX_PG,
- input wire BMC_VR_PG,
-
- // I2C
- inout wire SCL,
- inout wire SDA,
-
- // Second CPU Present Detection
- input wire CPUB_PRESENT_N,
- output wire CPUB_CLK_OEA,
- output wire CPUB_CLK_OEB,
-
- // Resets
- output wire LPC_RST,
- input wire BMC_SOFTWARE_PG,
- output wire BMC_RST,
- output wire FAN_RST,
- output wire USBHUB_RST,
- output wire CPU_STBY_RST,
-
- // Reserved for Future Use
- output wire DUAL_5V_CTRL,
- output wire WINDOW_OPEN_N
- );
-
- // FUTURE update version
- parameter cpld_version = 8'b00000110;
- parameter rail_size = 15;
- wire [rail_size - 1:0] EN_BUF = 1'b0;
- wire [rail_size - 1:0] PG_BUF;
- wire SYSGOOD_BUF;
- wire CLK_IN;
- 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_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
- // 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;
- reg ERR_FOUND = 1'b0; // signal FIRST_DELAY : STD_LOGIC := '1';
- wire CLEAR_ERR = 1'b0; //i2c signals
- wire i2c_read_req;
- reg [7:0] i2c_data_to_master = 8'b00000000;
- wire [7:0] i2c_data_from_master;
- wire i2c_data_valid;
- wire i2c_rst = 1'b0;
- reg [7:0] i2c_reg_cur = 8'b00000000;
- parameter i2c_addr = 7'b0110001;
- parameter i2c_clr_err_addr = 8'b00000011;
- parameter i2c_pg_reg_addr1 = 8'b00000101;
- parameter i2c_pg_reg_addr2 = i2c_pg_reg_addr1 + 1;
- parameter i2c_status_reg_addr = i2c_pg_reg_addr2 + 1;
- parameter i2c_version_reg_addr = 8'b00000000;
- reg [15:0] i2c_pg_reg = 1'b0;
- reg i2c_clr_err = 1'b0;
-
- OSCH OSC1(
- .STDBY(1'b0),
- .OSC(CLK_IN),
- .SEDSTDBY(stdby_sed)
- );
-
- //debug
- //CLEAR_ERR <= DUAL_5V_CTRL;
- //Divide input 33MHz clock down to 4.125MHz
- // process (CLK_IN)
- // begin
- // if (rising_edge(CLK_IN)) then
- // CLK_REG <= CLK_REG + 1;
- // end if;
- // end process;
- // CLK_DIV <= STD_LOGIC(CLK_REG(2));
- // Power Sequencer Instance
- // SEQ1: entity work.pwrseq
- // generic map(rail_size)
- // port map(
- // EN => EN_BUF,
- // PGOOD_A => PG_BUF,
- // SYSEN_A => SYSEN_BUF,
- // SYSGOOD => SYSGOOD_BUF,
- // SCL => SCL,
- // SDA => SDA,
- // CLK_IN => CLK_DIV
- // CLK_IN => CLK_IN
- // );
- //I2C device
- I2C_slave #(
- i2c_addr)
- I2C_SLAVE(
- SCL,
- SDA,
- CLK_IN,
- i2c_rst,
- i2c_read_req,
- i2c_data_to_master,
- i2c_data_valid,
- i2c_data_from_master);
-
- assign i2c_rst = 1'b0;
- //Handle I2C
- //2 8-bit registers with PGOOD state on error
- always @(posedge CLK_IN) begin
- i2c_clr_err <= 1'b0;
-
- if (i2c_data_valid == 1'b1) begin
- // data from master is register to be read
- i2c_reg_cur <= i2c_data_from_master;
-
- //pulse clear err signal if i2c master reads register 0x03
- if (((i2c_data_from_master) == i2c_clr_err_addr)) begin
- i2c_clr_err <= 1'b1;
- end
- end
- else if (i2c_read_req == 1'b1) begin
- i2c_reg_cur <= i2c_reg_cur + 1;
- end
- case(i2c_reg_cur)
- i2c_clr_err_addr : begin
- i2c_data_to_master <= 8'b11111111;
- end
- i2c_pg_reg_addr1 : begin
- i2c_data_to_master <= i2c_pg_reg[15:8];
- end
- i2c_pg_reg_addr2 : begin
- i2c_data_to_master <= i2c_pg_reg[7:0];
- end
- i2c_status_reg_addr : begin
- //FUTURE add CPU1 Present detect
- i2c_data_to_master <= {3'b000,WAIT_ERR,OPERATION_ERR,ERR_FOUND,SYSEN_BUF,SYSGOOD_BUF};
- end
- i2c_version_reg_addr : begin
- i2c_data_to_master <= cpld_version;
- end
- default : begin
- i2c_data_to_master <= 8'b00000000;
- end
- endcase
- end
-
- always @(posedge CLK_IN) begin
- PG_S1 <= PG_BUF;
- PG_S2 <= PG_S1;
- SYSEN_S1 <= SYSEN_BUF;
- SYSEN_S2 <= SYSEN_S1;
- SEQ_S1 <= SEQ_CONT;
- SEQ_S2 <= SEQ_S1;
- if ((CLEAR_ERR == 1'b1)) begin
- WAIT_ERR <= 1'b0;
- OPERATION_ERR <= 1'b0;
- ERR_FOUND <= 1'b0;
- W_COUNT <= {24{1'b0}};
- D_COUNT <= {17{1'b0}};
- end
- 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}};
- end
- else if ((PG_S2[0] == 1'b1 && EN_BUF[0] == 1'b1 && DELAY_DONE[0] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[0] <= 1'b1;
- end
- end
- else if ((PG_S2[1] == 1'b1 && EN_BUF[1] == 1'b1 && DELAY_DONE[1] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[1] <= 1'b1;
- end
- end
- else if ((PG_S2[2] == 1'b1 && EN_BUF[2] == 1'b1 && DELAY_DONE[2] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[2] <= 1'b1;
- end
- end
- else if ((PG_S2[3] == 1'b1 && EN_BUF[3] == 1'b1 && DELAY_DONE[3] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[3] <= 1'b1;
- end
- end
- else if ((PG_S2[4] == 1'b1 && EN_BUF[4] == 1'b1 && DELAY_DONE[4] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[4] <= 1'b1;
- end
- end
- else if ((PG_S2[5] == 1'b1 && EN_BUF[5] == 1'b1 && DELAY_DONE[5] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[5] <= 1'b1;
- end
- end
- else if ((PG_S2[6] == 1'b1 && EN_BUF[6] == 1'b1 && DELAY_DONE[6] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[6] <= 1'b1;
- end
- end
- else if ((PG_S2[7] == 1'b1 && EN_BUF[7] == 1'b1 && DELAY_DONE[7] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[7] <= 1'b1;
- end
- end
- else if ((PG_S2[8] == 1'b1 && EN_BUF[8] == 1'b1 && DELAY_DONE[8] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[8] <= 1'b1;
- end
- end
- else if ((PG_S2[9] == 1'b1 && EN_BUF[9] == 1'b1 && DELAY_DONE[9] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[9] <= 1'b1;
- end
- end
- else if ((PG_S2[10] == 1'b1 && EN_BUF[10] == 1'b1 && DELAY_DONE[10] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[10] <= 1'b1;
- end
- end
- else if ((PG_S2[11] == 1'b1 && EN_BUF[11] == 1'b1 && DELAY_DONE[11] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[11] <= 1'b1;
- end
- end
- else if ((PG_S2[12] == 1'b1 && EN_BUF[12] == 1'b1 && DELAY_DONE[12] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[12] <= 1'b1;
- end
- end
- else if ((PG_S2[13] == 1'b1 && EN_BUF[13] == 1'b1 && DELAY_DONE[13] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[13] <= 1'b1;
- end
- end
- else if ((PG_S2[14] == 1'b1 && EN_BUF[14] == 1'b1 && DELAY_DONE[14] == 1'b0)) begin
- W_COUNT <= {24{1'b0}};
- D_COUNT <= D_COUNT + 1;
- if ((D_COUNT[16] == 1'b1)) begin
- D_COUNT <= {17{1'b0}};
- DELAY_DONE[14] <= 1'b1;
- end
- end
-
- // Error Checks
- // Check time between Enables going high and PGOODs arriving. Error out after 100ms
- else if ((PG_S2[0] == 1'b0 && EN_BUF[0] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[1] == 1'b0 && EN_BUF[1] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[2] == 1'b0 && EN_BUF[2] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[3] == 1'b0 && EN_BUF[3] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[4] == 1'b0 && EN_BUF[4] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[5] == 1'b0 && EN_BUF[5] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[6] == 1'b0 && EN_BUF[6] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[7] == 1'b0 && EN_BUF[7] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[8] == 1'b0 && EN_BUF[8] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[9] == 1'b0 && EN_BUF[9] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[10] == 1'b0 && EN_BUF[10] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[11] == 1'b0 && EN_BUF[11] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[12] == 1'b0 && EN_BUF[12] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[13] == 1'b0 && EN_BUF[13] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- else if ((PG_S2[14] == 1'b0 && EN_BUF[14] == 1'b1)) begin
- W_COUNT <= W_COUNT + 1;
- if ((W_COUNT[23] == 1'b1)) begin
- W_COUNT <= {24{1'b0}};
- WAIT_ERR <= 1'b1;
- end
- end
- if ((( ~(DELAY_DONE & ~PG_S2)) != railarray_1)) begin
- OPERATION_ERR <= 1'b1;
- end
- if (((WAIT_ERR | OPERATION_ERR) == 1'b1 && CLEAR_ERR == 1'b0)) begin
- ERR_FOUND <= 1'b1;
- end else begin
- i2c_pg_reg[14:0] <= PG_S2[14:0];
- end
- 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;
-
- // 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]);
-
- // Enable outputs
- // Shut everything off if ann 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;
-
- //ERR state reset
- assign CLEAR_ERR = i2c_clr_err;
-
- // CPUB clk enables
- assign CPUB_CLK_OEA = ~CPUB_PRESENT_N;
- assign CPUB_CLK_OEB = ~CPUB_PRESENT_N;
-
- // System PWRGOOD
- assign SYSGOOD_BUF = DELAY_DONE[14];
- assign SYSGOOD = SYSGOOD_BUF & BMC_SOFTWARE_PG;
- assign LPC_RST = SYSGOOD_BUF;
-
- // CPU Reset
- assign CPU_STBY_RST = EN_BUF[0];
-
- // BMC RESETs
- assign BMC_RST = BMC_VR_PG;
- assign USBHUB_RST = SYSGOOD_BUF & BMC_SOFTWARE_PG;
- assign FAN_RST = ~BMC_VR_PG;
-
- // DEBUG_IN override allows non-BMC control of CPLD
- assign SYSEN_BUF = SYSEN | ~DEBUG_IN;
- // assign SYSEN_BUF = ~DEBUG_IN;
-
-endmodule \ No newline at end of file
OpenPOWER on IntegriCloud