diff --git a/.gitignore b/.gitignore
index c589414..2f43ce4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,87 +18,35 @@ Thumbs.db
.opencode/
# ===========================
-# Vivado / Vitis (Zynq)
+# 通用: 日志、报告、中间文件
# ===========================
-
-# 日志与报告
*.jou
*.log
+*.rpt
*.pb
*.wdb
-*.rpt
*.sdf
*.vcd
+*.ptwx
+*.fdo
+*.fdc
+*.sr
-# 生成的可编程文件(先统一忽略,下面再恢复需要的)
-*.bin
-*.mcs
-*.prm
-*.rbt
-*.bgn
-*.cfi
-*.elf
-*.ltx
-*.mif
-*.mmi
-*.nky
-*.obj
-*.opt
-*.xml
-*.Xil
-*.xise
-*.xpa
-*.xtx
-*.xwbt
-*.do
-*.csv
-
-# 工具生成目录
-.Xil/
-.vivado/
-.runs/
-.srcs/
-.gen/
-.cache/
-.data/
-.hw/
-.ip_user_files/
-/sim/
-/synth/
-/impl/
-/hw_handoff/
-/sdk/
-/export/
-/.vs/
-*.bld
-*.ipdefs
-*.tmp/
-
-# 部分软件输出
+# ===========================
+# 通用: 编译/构建产物
+# ===========================
*.o
*.a
*.d
-*.fsbl
-*.ssbl
-*.bit.bin # 非.bit的二进制位流
-*.hdf
-*.xsa
-*.mss
-
-# 临时pid/错误文件
-vivado_pid*.str
-vivado_pid*.debug
-hs_err_pid*.log
-webtalk*.jou
-webtalk*.log
-usage_statistics_webtalk.*
+*.obj
+*.tmp/
+*.bld
+*.ipdefs
# ===========================
-# Lattice Diamond / Radiant
+# Lattice Diamond / Radiant (CPLD)
# ===========================
-
-# 综合与布局布线临时文件
-*.dir/
+# 综合与布局布线输出
*.rrr
*.twr
*.tdo
@@ -108,43 +56,150 @@ usage_statistics_webtalk.*
*.par
*.ngd
*.ncd
-*.ptwx
*.srr
-*.sdf
*.xrf
*.recovery
*.sty
*.prf
-*.tcl # 注意:只忽略生成脚本,手写的.tcl请放在独立目录或明确跟踪
-*.tcl.old
-*.tcl.bak
-*cache
-*gen
-
-# 工具生成目录
+# Lattice 项目目录
/impl/
+/impl1/
/_diamond/
/radiant_project/
-*.ldf
-*.ipxact
-*.sbx
+*_tcr.dir/
-# 日志
-*.log
-*.jou
+# Lattice 生成/临时文件
+*cache
+*gen
+transcript
+hdlparser.log
+pn*.dmp
+promote.xml
+reportview.xml
+*.html
+*.htm
+debug.rvl
+debug.rvs
+*.svf
+*.rva
+*.trc
+
+# Lattice 脚本(生成/自动的)
+*.tcl
+*.tcl.old
+*.tcl.bak
+*.spf
+*.mdo
+*.tops
+*.sort
+*.ado
+*.cr.mti
+*.mpf
+
+# ModelSim / Questa 仿真
+vsim.wlf
+work/
+*_math_real.vhd
+*_ieee_2008.vhd
# ===========================
-# 明确保留的文件
+# Xilinx Vivado / Vitis (Zynq/PGA)
# ===========================
-# 保留所有 .bit 和 .jed 文件
-!*.bit
-!*.jed
+# Vivado 生成目录(项目名前缀)
+*.runs/
+*.cache/
+*.hw/
+*.ip_user_files/
+*.sim/
+*.gen/
+*.tmp/
+*.data/
-# 额外建议保留的约束/源文件(如果某些规则误伤,可在此恢复)
-# 例如 Lattice 的逻辑偏好文件通常是手写的,避免被 *.tcl 规则误删
+# Vivado 独立目录
+.Xil/
+.vivado/
+.hw/
+.ip_user_files/
+/sim/
+/synth/
+/hw_handoff/
+/sdk/
+/export/
+/.vs/
+/webtalk/
+
+# impl_1 / synth_1(Vivado runs 目录下的子目录)
+impl_1/
+synth_1/
+
+# Vitis 产物
+*.fsbl
+*.ssbl
+*.bit.bin
+*.hdf
+*.xsa
+*.mss
+*.elf
+
+# Vivado 其他
+*.bin
+*.mcs
+*.prm
+*.rbt
+*.bgn
+*.cfi
+*.ltx
+*.mif
+*.mmi
+*.nky
+*.opt
+*.xml
+*.Xil
+*.xise
+*.xpa
+*.xtx
+*.xwbt
+*.do
+*.csv
+*.xci
+*.bda
+
+# Vivado 统计
+vivado_pid*.str
+vivado_pid*.debug
+hs_err_pid*.log
+webtalk*.jou
+webtalk*.log
+usage_statistics_webtalk.*
+
+# ===========================
+# 明确保留的文件(放在最后,覆盖上面的忽略规则)
+# ===========================
+# Verilog / SystemVerilog 源码
+!*.v
+!*.sv
+
+# 约束文件
!*.lpf
!*.xdc
!*.pcf
!*.sdc
-!*.elf
\ No newline at end of file
+
+# Lattice 项目文件
+!*.ccl
+!*.ldf
+
+# 位流和编程文件
+!*.bit
+!*.jed
+
+# 手写脚本
+!*.py
+
+# 文档
+*.xlsx
+*.xls
+*.doc
+*.docx
+*.pdf
diff --git a/2.FW/CPLD1/.floorplanner.ini b/2.FW/CPLD1/.floorplanner.ini
new file mode 100644
index 0000000..55fab21
--- /dev/null
+++ b/2.FW/CPLD1/.floorplanner.ini
@@ -0,0 +1,14 @@
+[General]
+showNCD=true
+showPgroups=true
+showCongestion=false
+showConnsSelect=false
+showConnsBetween=true
+showConnsOutside=true
+showLPF=true
+showREGIONs=true
+showUGROUPs=true
+showPARITIONs=true
+showLogicalConnections=false
+dontShowBBoxOverlapWarning=false
+sceneInViewRect=@Variant(\0\0\0\x14\xc0\xe7\x8f\x66\xc9\x44\x30\xff\xc0\x9a\x44\xe8X\xd3\x9d\x35\x41\x10>h\xdf\xba\r\xb6@\xfaOjO]\x8bt)
diff --git a/2.FW/CPLD1/.gitignore b/2.FW/CPLD1/.gitignore
new file mode 100644
index 0000000..bd935a3
--- /dev/null
+++ b/2.FW/CPLD1/.gitignore
@@ -0,0 +1,3 @@
+# Lattice Diamond 实现输出目录
+# 根目录 .gitignore 已覆盖大部分 pattern,此处仅确保 impl1/ 被忽略
+impl1/
diff --git a/2.FW/CPLD1/.run_manager.ini b/2.FW/CPLD1/.run_manager.ini
new file mode 100644
index 0000000..cfb561e
--- /dev/null
+++ b/2.FW/CPLD1/.run_manager.ini
@@ -0,0 +1,9 @@
+[Runmanager]
+Geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\0\0\0\0\x3\x30\0\0\x1!\0\0\x4\x11\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0)
+windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x1\0\0\0\0\0\0\0\x1\xff\xff\xff\xff\x3\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
+headerState=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x16\0\xe0?\0\0\0\t\0\0\0\x10\0\0\0\x64\0\0\0\xf\0\0\0\x64\0\0\0\xe\0\0\0\x64\0\0\0\r\0\0\0\x64\0\0\0\x15\0\0\0\x64\0\0\0\x14\0\0\0\x64\0\0\0\x13\0\0\0\x64\0\0\0\x12\0\0\0\x64\0\0\0\x11\0\0\0\x64\0\0\x4\xd3\0\0\0\x16\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x3\0\0\0#\0\0\0\x1\0\0\0\x2\0\0\x4\xb0\0\0\0\f\0\0\0\0\0\0\0\0\0\0\0\t\0\0\0\0)
+
+[impl1%3CStrategy1%3E]
+isChecked=false
+isHidden=false
+isExpanded=false
diff --git a/2.FW/CPLD1/.setting.ini b/2.FW/CPLD1/.setting.ini
new file mode 100644
index 0000000..aca71f1
--- /dev/null
+++ b/2.FW/CPLD1/.setting.ini
@@ -0,0 +1,4 @@
+[General]
+Export.auto_tasks=Bitgen, Jedecgen
+AutoAssign=false
+Map.auto_tasks=MapTrace, MapVerilogSimFile
diff --git a/2.FW/CPLD1/.spread_sheet.ini b/2.FW/CPLD1/.spread_sheet.ini
new file mode 100644
index 0000000..6c511f4
--- /dev/null
+++ b/2.FW/CPLD1/.spread_sheet.ini
@@ -0,0 +1,3 @@
+[General]
+COLUMN_POS_INFO_NAME_-1_0=Prioritize
+COLUMN_POS_INFO_NAME_-1_1=PIO Register
diff --git a/2.FW/CPLD1/.spreadsheet_view.ini b/2.FW/CPLD1/.spreadsheet_view.ini
new file mode 100644
index 0000000..d75bc4f
--- /dev/null
+++ b/2.FW/CPLD1/.spreadsheet_view.ini
@@ -0,0 +1,76 @@
+[General]
+pin_sort_type=0
+pin_sort_ascending=true
+sig_sort_type=0
+sig_sort_ascending=true
+active_Sheet=Port Assignments
+
+[Port%20Assignments]
+Name="202,0"
+Group%20By="111,1"
+Pin="62,2"
+BANK="85,3"
+BANK_VCC="125,4"
+VREF="81,5"
+IO_TYPE="216,6"
+PULLMODE="127,7"
+DRIVE="86,8"
+SLEWRATE="126,9"
+CLAMP="95,10"
+OPENDRAIN="133,11"
+DIFFRESISTOR="155,12"
+DIFFDRIVE="122,13"
+HYSTERESIS="140,14"
+Outload%20%28pF%29="133,15"
+MaxSkew="111,16"
+Clock%20Load%20Only="165,17"
+SwitchingID="129,18"
+Ground%20plane%20PCB%20noise%20%28mV%29="267,19"
+Power%20plane%20PCB%20noise%20%28mV%29="257,20"
+SSO%20Allowance%28%25%29="181,21"
+sort_columns="Name,Ascending"
+
+[Pin%20Assignments]
+Pin="102,0"
+Pad%20Name="116,1"
+Dual%20Function="144,2"
+Polarity="97,3"
+BANK="0,4"
+BANK_VCC="125,5"
+IO_TYPE="105,6"
+Signal%20Name="134,7"
+Signal%20Type="127,8"
+sort_columns="Pin,Ascending"
+
+[Clock%20Resource]
+Clock%20Type="100,ELLIPSIS"
+Clock%20Name="215,ELLIPSIS"
+Selection="100,ELLIPSIS"
+
+[Global%20Preferences]
+Preference%20Name="234,ELLIPSIS"
+Preference%20Value="227,ELLIPSIS"
+
+[Cell%20Mapping]
+Type="100,ELLIPSIS"
+Name="100,ELLIPSIS"
+Din\Dout="100,ELLIPSIS"
+PIO%20Register="100,ELLIPSIS"
+
+[Route%20Priority]
+Type="100,ELLIPSIS"
+Name="100,ELLIPSIS"
+Prioritize="100,ELLIPSIS"
+
+[Timing%20Preferences]
+Preference%20Name="140,ELLIPSIS"
+Preference%20Value="138,ELLIPSIS"
+Preference%20Unit="128,ELLIPSIS"
+
+[Group]
+Group%20Type\Name="147,ELLIPSIS"
+Value="51,ELLIPSIS"
+
+[Misc%20Preferences]
+Preference%20Name="140,ELLIPSIS"
+Preference%20Value="138,ELLIPSIS"
diff --git a/2.FW/CPLD1/BUS_Con.v b/2.FW/CPLD1/BUS_Con.v
new file mode 100644
index 0000000..cc61c73
--- /dev/null
+++ b/2.FW/CPLD1/BUS_Con.v
@@ -0,0 +1,215 @@
+module BUS_Con (
+ input i_sys_clk,
+ input i_rst_n,
+
+ // SPI Interface
+ input i_sclk,
+ input i_mosi,
+ input i_cs,
+ output o_miso, // <-- MISO Logic added here
+
+ // Local Interface
+ output o_rvalid, // (Typo in original: o_rvalid)
+ input i_rvalid, // Valid signal from Backend (Data is ready)
+ input i_wvalid,
+ output o_wready,
+ input i_reg_busy,
+ input [23:0] i_rdata, // Data from Backend to send to Master
+ output o_wr,
+ output o_cmd_valid,
+ output [23:0] o_data,
+ output [6:0] o_addr,
+ output o_err
+);
+
+ // --- 1. Synchronization ---
+ reg [1:0] cs_sync;
+ reg [1:0] sclk_sync;
+ reg [1:0] mosi_sync;
+
+ wire cs_active;
+ wire cs_rise;
+ wire sclk_rise; // For Sampling MOSI
+ wire sclk_fall; // For Shifting MISO
+ wire mosi_data;
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ cs_sync <= 2'b11;
+ sclk_sync <= 2'b00;
+ mosi_sync <= 2'b00;
+ end else begin
+ cs_sync <= {cs_sync[0], i_cs};
+ sclk_sync <= {sclk_sync[0], i_sclk};
+ mosi_sync <= {mosi_sync[0], i_mosi};
+ end
+ end
+
+ assign cs_active = ~cs_sync[1];
+ assign cs_rise = (!cs_sync[1] && cs_sync[0]);
+
+ // SPI Mode 0: Sample MOSI on Rising, Shift MISO on Falling
+ assign sclk_rise = (!sclk_sync[1] && sclk_sync[0]);
+ assign sclk_fall = (sclk_sync[1] && !sclk_sync[0]); // Logic for MISO
+ assign mosi_data = mosi_sync[1];
+
+ // --- 2. MOSI (Receive) Logic ---
+ reg [31:0] recv_reg;
+ reg [5:0] bit_cnt;
+ reg data_ready;
+ reg err_flag;
+ reg [1:0] state;
+ //
+ reg [31:0] tx_buffer; // Holds data waiting for the next CS Low
+ reg [31:0] miso_shift; // The actual shifter
+ // Output Registers
+ reg [6:0] addr_out;
+ reg [23:0] data_out;
+ reg wr_out;
+ reg cmd_valid_out;
+
+ //
+ localparam IDLE = 2'b00;
+ localparam CMD_SENT = 2'b01;
+ localparam WAIT_BUSY = 2'b10;
+ localparam DONE = 2'b11;
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ recv_reg <= 32'd0;
+ bit_cnt <= 6'd0;
+ data_ready <= 1'b0;
+ err_flag <= 1'b0;
+ end
+ else begin
+ data_ready <= 1'b0;
+
+ if (cs_active) begin
+ if (sclk_rise) begin
+ recv_reg <= {recv_reg[30:0], mosi_data};
+ bit_cnt <= bit_cnt + 1'b1;
+ end
+ else if (cs_rise) begin
+ if (bit_cnt == 6'd32) begin
+ data_ready <= 1'b1;
+ err_flag <= 1'b0;
+ bit_cnt <= 6'd0;
+ end
+ else if (bit_cnt != 0) begin
+ err_flag <= 1'b1;
+ bit_cnt <= 6'd0;
+ recv_reg <= 'd0;
+ end
+ end
+ end
+ if (state == DONE) begin
+ recv_reg <= 'd0;
+ end
+ end
+ end
+
+ // --- 3. MISO (Transmit) Logic ---
+ // Protocol: We shift out 32 bits.
+ // Format: [8 bit Status/Padding] + [24 bit i_rdata]
+
+
+ // Capture data from backend when valid
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ tx_buffer <= 32'd0;
+ end else begin
+ // If backend provides valid read data, store it.
+ // We pad the top 8 bits with Zeros (or you can put status flags here)
+ if (i_rvalid) begin
+ tx_buffer <= {8'h00, i_rdata};
+ end
+ end
+ end
+
+ // Shift data out
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ miso_shift <= 32'd0;
+ end else begin
+ if (!cs_active) begin
+ // Pre-load the shifter while CS is High
+ // This ensures Bit 31 is ready BEFORE the first clock edge
+ miso_shift <= tx_buffer;
+ end else begin
+ // Shift on Falling Edge (Master samples on Rising)
+ if (sclk_fall) begin
+ miso_shift <= {miso_shift[30:0], 1'b0};
+ end
+ end
+ end
+ end
+
+ // Tri-state MISO when CS is high (optional, usually good practice)
+ // If your board doesn't need tristate, just use: assign o_miso = miso_shift[31];
+ assign o_miso = (cs_active) ? miso_shift[31] : 1'bz;
+
+ // --- 4. Register Control FSM ---
+
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ state <= IDLE;
+ cmd_valid_out <= 1'b0;
+ addr_out <= 7'd0;
+ data_out <= 24'd0;
+ wr_out <= 1'b0;
+ end else begin
+ case (state)
+ IDLE: begin
+ if (data_ready) begin
+ addr_out <= recv_reg[30:24];
+ data_out <= recv_reg[23:0];
+ wr_out <= recv_reg[31];
+
+ if (!i_reg_busy) begin
+ cmd_valid_out <= 1'b1;
+ state <= CMD_SENT;
+ end else begin
+ state <= WAIT_BUSY;
+ end
+ end
+ end
+
+ WAIT_BUSY: begin
+ if (!i_reg_busy) begin
+ cmd_valid_out <= 1'b1;
+ state <= CMD_SENT;
+ end
+ end
+
+ CMD_SENT: begin
+ cmd_valid_out <= 1'b0;
+ state <= DONE;
+ end
+
+ DONE: begin
+ if (!i_reg_busy) begin
+ state <= IDLE;
+ addr_out <= 'd0;
+ data_out <= 'd0;
+ wr_out <= 'd0;
+ end
+ end
+ endcase
+ end
+ end
+
+ assign o_addr = addr_out;
+ assign o_data = data_out;
+ assign o_wr = wr_out;
+ assign o_cmd_valid = cmd_valid_out;
+ assign o_err = err_flag;
+ assign o_wready = (state == IDLE);
+
+ // Pass through unused signal or hook it up if needed
+ assign o_rvalid = 1'b0;
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD1/CPLD_Con.v b/2.FW/CPLD1/CPLD_Con.v
new file mode 100644
index 0000000..4f9c1e3
--- /dev/null
+++ b/2.FW/CPLD1/CPLD_Con.v
@@ -0,0 +1,190 @@
+module CPLD_Con (
+ input i_sys_clk,
+ input i_rst_n,
+ input i_con_exec,
+ input [23:0]i_freq_relay1,
+ input [23:0]i_freq_relay2,
+ input [23:0]i_freq_relay3,
+ input [23:0]i_freq_relay4,
+ output o_con_done,
+ output [3:0]o_OC_x01,
+ output [3:0]o_OC_x17,
+ output [18:0]o_DMM_EN,
+ output o_IO_RC1,
+ output [4:0]o_RC_Tx,
+ output o_err
+);
+
+ //Relay Reg
+ reg [3:0]OC_x01 ;
+ reg [3:0]OC_x17 ;
+ reg [18:0]DMM_en ;
+
+ reg[4:0]RC_Tx;
+ reg io_RC;
+
+ //Flags
+ reg exec_flag;
+ reg err_flag;
+ reg [3:0]slot_exec_flag;
+ reg done_flag;
+
+ //Counter
+ reg [15:0]delay_cnt;
+
+ always @(posedge i_sys_clk) begin
+ if (i_rst_n == 1'b0) begin
+ delay_cnt <= 'd0;
+ end
+ else begin
+ if (exec_flag == 1'b1) begin
+ delay_cnt <= delay_cnt + 1'd1;
+ end
+ else begin
+ delay_cnt <= 'd0;
+ end
+ end
+ end
+
+ always @(posedge i_sys_clk) begin
+ if (i_rst_n == 1'b0) begin
+ exec_flag <= 1'b0;
+ err_flag <= 1'b0;
+ slot_exec_flag <= 'd0;
+
+ OC_x01 <= 'd0;
+ OC_x17 <= 'd0;
+ io_RC <= 'd0;
+ done_flag <= 'd1;
+ end
+ else begin
+ if ((i_con_exec == 1'b1) & (exec_flag == 1'b0)) begin
+ exec_flag <= 1'b1;
+ done_flag <= 1'b0;
+ //To DO: More Sanity Check?
+ if (i_freq_relay1[0] && i_freq_relay2[0] && i_freq_relay3[0] && i_freq_relay4[0]) begin
+ err_flag <= 1'b1;
+ end
+ else begin
+ slot_exec_flag[0] <= i_freq_relay1[0];
+ slot_exec_flag[1] <= i_freq_relay2[0];
+ slot_exec_flag[2] <= i_freq_relay3[0];
+ slot_exec_flag[3] <= i_freq_relay4[0];
+ RC_Tx <= i_freq_relay4[14:10];
+ end
+ end
+ else if (exec_flag == 1'b1) begin
+ io_RC <= i_freq_relay1[0] || i_freq_relay2[0] || i_freq_relay3[0] || i_freq_relay4[0];
+ case (slot_exec_flag)
+ 4'b0001: begin
+ if (i_freq_relay1[9:1] < 9) begin
+ OC_x01 <= 4'b0001;
+ OC_x17 <= 'd0;
+ DMM_en <= 19'b000_0000_0000_0000_0001;
+ end
+ else if (i_freq_relay1[9:1] < 73) begin
+ DMM_en <= 19'b000_0000_0000_0000_0010;
+ OC_x01 <= 'd0;
+ OC_x17 <= 'd0;
+ end
+ else if (i_freq_relay1[9:1] < 137) begin
+ OC_x17 <= 4'b0001;
+ OC_x01 <= 'd0;
+ DMM_en <= 19'b000_0000_0000_0000_0100;
+ end
+ else begin
+ DMM_en <= 19'b000_0000_0000_0000_1000;
+ OC_x01 <= 'd0;
+ OC_x17 <= 'd0;
+ end
+ end
+ 4'b0010: begin
+ if (i_freq_relay2[9:1] < 9) begin
+ OC_x01 <= 4'b0010;
+ OC_x17 <= 'd0;
+ DMM_en <= 19'b000_0000_0000_0001_0000;
+ end
+ else if (i_freq_relay2[9:1] < 73) begin
+ DMM_en <= 19'b000_0000_0000_0010_0000;
+ OC_x01 <= 'd0;
+ OC_x17 <= 'd0;
+ end
+ else if (i_freq_relay2[9:1] < 137) begin
+ OC_x17 <= 4'b0010;
+ OC_x01 <= 'd0;
+ DMM_en <= 19'b000_0000_0000_0100_0000;
+ end
+ else begin
+ OC_x01 <= 'd0;
+ OC_x17 <= 'd0;
+ DMM_en <= 19'b000_0000_0000_1000_0000;
+ end
+ end
+ 4'b0100: begin
+ if (i_freq_relay3[9:1] < 9) begin
+ OC_x01 <= 'b0100;
+ OC_x17 <= 'd0;
+ DMM_en <= 19'b000_0000_0001_0000_0000;
+ end
+ else if ((i_freq_relay3[9:1] > 64)& (i_freq_relay3[9:1] < 73)) begin
+ OC_x01 <= 4'b0000;
+ OC_x17 <= 'd0;
+ DMM_en <= 19'b000_0000_0010_0000_0000;
+ end
+ else if (i_freq_relay3[9:1] < 137) begin
+ DMM_en <= 19'b000_0000_0100_0000_0000;
+ OC_x01 <= 'd0;
+ OC_x17 <= 'b0100;
+ end
+ else if (i_freq_relay3[9:1] < 201) begin
+ OC_x17 <= 4'd0;
+ OC_x01 <= 'd0;
+ DMM_en <= 16'b000_0000_1000_0000_0000;
+ end
+ end
+ 4'b1000: begin
+ if (i_freq_relay4[9:1] < 9) begin
+ OC_x01 <= 4'b1000;
+ OC_x17 <= 'd0;
+ DMM_en <= 19'b000_0001_0000_0000_0000;
+ end
+ else if (i_freq_relay4[9:1] < 72) begin
+ DMM_en <= 19'b000_0010_0000_0000_0000;
+ OC_x01 <= 'd0;
+ OC_x17 <= 'd0;
+ end
+ else if (i_freq_relay4[9:1] < 137) begin
+ OC_x17 <= 4'b1000;
+ OC_x01 <= 'd0;
+ DMM_en <= 19'b000_0100_0000_0000_0000;
+ end
+ else begin
+ OC_x01 <= 'd0;
+ OC_x17 <= 'd0;
+ DMM_en <= 19'b000_1000_0000_0000_0000;
+ end
+ end
+ default: begin
+ OC_x01 <= 4'b0000;
+ OC_x17 <= 4'b0000;
+ DMM_en <= 'd0;
+ end
+ endcase
+ done_flag <= 1'b1;
+ end
+ end
+ if (done_flag == 1) begin
+ exec_flag <= 1'b0;
+ end
+ end
+
+ assign o_con_done = done_flag;
+ assign o_DMM_EN = DMM_en;
+ assign o_OC_x01 = OC_x01;
+ assign o_OC_x17 = OC_x17;
+ assign o_IO_RC1 = io_RC;
+ assign o_err = err_flag;
+ assign o_RC_Tx = RC_Tx;
+
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD1/NewExtIns_CPLD1.ccl b/2.FW/CPLD1/NewExtIns_CPLD1.ccl
new file mode 100644
index 0000000..dcf391b
--- /dev/null
+++ b/2.FW/CPLD1/NewExtIns_CPLD1.ccl
@@ -0,0 +1 @@
+VERSION=20110520
diff --git a/2.FW/CPLD1/NewExtIns_CPLD1.ldf b/2.FW/CPLD1/NewExtIns_CPLD1.ldf
new file mode 100644
index 0000000..9f8a17b
--- /dev/null
+++ b/2.FW/CPLD1/NewExtIns_CPLD1.ldf
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2.FW/CPLD1/NewExtIns_CPLD1.lpf b/2.FW/CPLD1/NewExtIns_CPLD1.lpf
new file mode 100644
index 0000000..3e865a0
--- /dev/null
+++ b/2.FW/CPLD1/NewExtIns_CPLD1.lpf
@@ -0,0 +1,247 @@
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+BLOCK RESETPATHS ;
+BLOCK ASYNCPATHS ;
+LOCATE COMP "i_sys_clk" SITE "B9" ;
+LOCATE COMP "i_rst_n" SITE "Y14" ;
+LOCATE COMP "i_sclk" SITE "AA10" ;
+LOCATE COMP "i_cs" SITE "AB11" ;
+LOCATE COMP "i_mosi" SITE "AB12" ;
+LOCATE COMP "o_miso" SITE "AA14" ;
+LOCATE COMP "o_err" SITE "AB16" ;
+LOCATE COMP "o_DMM_EN[0]" SITE "F17" ;
+LOCATE COMP "o_DMM_EN[1]" SITE "E17" ;
+LOCATE COMP "o_DMM_EN[2]" SITE "D17" ;
+IOBUF PORT "i_cs" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_mosi" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_rst_n" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_sclk" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_miso" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=8 ;
+IOBUF PORT "o_rvaild" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_wready" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "i_sys_clk" DRIVE=NA IO_TYPE=LVCMOS33 SLEWRATE=NA PULLMODE=DOWN ;
+IOBUF PORT "o_err" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[1]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[2]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[3]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[4]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[5]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[6]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[7]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[8]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[9]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[10]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[11]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[12]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[13]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[14]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_DMM_EN[15]" IO_TYPE=LVCMOS33 ;
+LOCATE COMP "o_DMM_EN[3]" SITE "C17" ;
+LOCATE COMP "o_DMM_EN[4]" SITE "AB10" ;
+LOCATE COMP "o_DMM_EN[5]" SITE "AA11" ;
+LOCATE COMP "o_DMM_EN[6]" SITE "AA12" ;
+LOCATE COMP "o_DMM_EN[7]" SITE "AB13" ;
+LOCATE COMP "o_DMM_EN[8]" SITE "D15" ;
+LOCATE COMP "o_DMM_EN[9]" SITE "D14" ;
+LOCATE COMP "o_DMM_EN[10]" SITE "C13" ;
+LOCATE COMP "o_DMM_EN[11]" SITE "F12" ;
+LOCATE COMP "o_DMM_EN[12]" SITE "W12" ;
+LOCATE COMP "o_DMM_EN[13]" SITE "V12" ;
+LOCATE COMP "o_DMM_EN[14]" SITE "Y12" ;
+LOCATE COMP "o_DMM_EN[15]" SITE "V13" ;
+LOCATE COMP "o_IO_RC1" SITE "F10" ;
+IOBUF PORT "o_IO_RC1" IO_TYPE=LVCMOS33 ;
+BLOCK JTAGPATHS ;
+LOCATE COMP "o_OC_1[0]" SITE "M19" ;
+LOCATE COMP "o_OC_1[1]" SITE "R16" ;
+LOCATE COMP "o_OC_1[2]" SITE "N20" ;
+LOCATE COMP "o_OC_1[3]" SITE "P20" ;
+LOCATE COMP "o_OC_1[4]" SITE "G19" ;
+LOCATE COMP "o_OC_1[5]" SITE "J19" ;
+LOCATE COMP "o_OC_1[6]" SITE "H16" ;
+LOCATE COMP "o_OC_1[7]" SITE "J17" ;
+LOCATE COMP "o_OC_1[16]" SITE "W6" ;
+LOCATE COMP "o_OC_1[17]" SITE "AA7" ;
+LOCATE COMP "o_OC_1[18]" SITE "AB6" ;
+LOCATE COMP "o_OC_1[19]" SITE "Y7" ;
+LOCATE COMP "o_OC_1[20]" SITE "V4" ;
+LOCATE COMP "o_OC_1[21]" SITE "R6" ;
+LOCATE COMP "o_OC_1[22]" SITE "U4" ;
+LOCATE COMP "o_OC_1[23]" SITE "T5" ;
+LOCATE COMP "o_OC_2[0]" SITE "E16" ;
+LOCATE COMP "o_OC_2[1]" SITE "F16" ;
+LOCATE COMP "o_OC_2[2]" SITE "D16" ;
+LOCATE COMP "o_OC_2[3]" SITE "G15" ;
+LOCATE COMP "o_OC_2[4]" SITE "C22" ;
+LOCATE COMP "o_OC_2[5]" SITE "D20" ;
+LOCATE COMP "o_OC_2[6]" SITE "D21" ;
+LOCATE COMP "o_OC_2[7]" SITE "D22" ;
+LOCATE COMP "o_OC_2[16]" SITE "A17" ;
+LOCATE COMP "o_OC_2[17]" SITE "A18" ;
+LOCATE COMP "o_OC_2[18]" SITE "C18" ;
+LOCATE COMP "o_OC_2[19]" SITE "D18" ;
+LOCATE COMP "o_OC_2[20]" SITE "G13" ;
+LOCATE COMP "o_OC_2[21]" SITE "F15" ;
+LOCATE COMP "o_OC_2[22]" SITE "F13" ;
+LOCATE COMP "o_OC_2[23]" SITE "G12" ;
+LOCATE COMP "o_OC_3[0]" SITE "M3" ;
+LOCATE COMP "o_OC_3[1]" SITE "R1" ;
+LOCATE COMP "o_OC_3[2]" SITE "N2" ;
+LOCATE COMP "o_OC_3[3]" SITE "N1" ;
+LOCATE COMP "o_OC_3[4]" SITE "F19" ;
+LOCATE COMP "o_OC_3[5]" SITE "E19" ;
+LOCATE COMP "o_OC_3[7]" SITE "B20" ;
+LOCATE COMP "o_OC_3[6]" SITE "C20" ;
+LOCATE COMP "o_OC_3[16]" SITE "E8" ;
+LOCATE COMP "o_OC_3[17]" SITE "E9" ;
+LOCATE COMP "o_OC_3[18]" SITE "E10" ;
+LOCATE COMP "o_OC_3[19]" SITE "D11" ;
+LOCATE COMP "o_OC_3[20]" SITE "E7" ;
+LOCATE COMP "o_OC_3[21]" SITE "D8" ;
+LOCATE COMP "o_OC_3[22]" SITE "B8" ;
+LOCATE COMP "o_OC_4[0]" SITE "A13" ;
+LOCATE COMP "o_OC_4[1]" SITE "B13" ;
+LOCATE COMP "o_OC_4[2]" SITE "B14" ;
+LOCATE COMP "o_OC_4[3]" SITE "B15" ;
+LOCATE COMP "o_OC_4[4]" SITE "B19" ;
+LOCATE COMP "o_OC_4[5]" SITE "D12" ;
+LOCATE COMP "o_OC_4[6]" SITE "E14" ;
+LOCATE COMP "o_OC_4[7]" SITE "E15" ;
+LOCATE COMP "o_OC_4[16]" SITE "C15" ;
+LOCATE COMP "o_OC_4[17]" SITE "A16" ;
+LOCATE COMP "o_OC_4[18]" SITE "B16" ;
+LOCATE COMP "o_OC_4[19]" SITE "C16" ;
+LOCATE COMP "o_OC_4[20]" SITE "E12" ;
+LOCATE COMP "o_OC_4[21]" SITE "A21" ;
+LOCATE COMP "o_OC_4[22]" SITE "B22" ;
+LOCATE COMP "o_OC_4[23]" SITE "C21" ;
+IOBUF PORT "o_OC_1[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=8 ;
+IOBUF PORT "o_OC_1[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[8]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[8]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[8]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[8]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_1[16]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_2[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_2[16]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_3[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_3[16]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_4[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_4[16]" IO_TYPE=LVCMOS33 ;
diff --git a/2.FW/CPLD1/Reg_file.v b/2.FW/CPLD1/Reg_file.v
new file mode 100644
index 0000000..841ee6e
--- /dev/null
+++ b/2.FW/CPLD1/Reg_file.v
@@ -0,0 +1,167 @@
+module Reg_file (
+ input i_sys_clk,
+ input i_rst_n,
+
+ // Bus Interface
+ input i_wr_req,
+ input i_wr,
+ input [6:0] i_addr,
+ input [23:0] i_wdata,
+
+ output [23:0] o_rdata,
+ output o_rvalid,
+ output o_busy,
+ output o_err,
+
+ // Controller Interface
+ input i_con_done, // 1=IDLE/DONE, 0=BUSY
+ output o_exec,
+
+ // Direct Register Outputs
+ output [23:0] o_freq1,
+ output [23:0] o_freq2,
+ output [23:0] o_freq3,
+ output [23:0] o_freq4
+);
+
+ // --- Parameters ---
+ localparam REG_COUNT = 16;
+ localparam [23:0]
+ IDENT = 24'h200000 || 12'b0001_0000_0000, //CPLD1==1,version=1.0.0
+ STATE_INIT = 24'h800000;
+
+ // State Machine Definition
+ localparam IDLE = 4'd0;
+ localparam BUSY = 4'd1;
+ localparam EXEC_ACK = 4'd2; // Wait for controller to go BUSY (Done=0)
+ localparam EXEC_WAIT = 4'd3; // Wait for controller to go DONE (Done=1)
+
+ // --- Internal Signals ---
+ reg [3:0] state;
+ reg [23:0] regtable [0:REG_COUNT - 1];
+ reg [23:0] rdata_reg;
+
+ reg busy_flag;
+ reg err_flag;
+ reg rvalid_flag;
+
+ integer i;
+
+ // Mapping Control Bits
+ wire exec_bit = regtable[1][0];
+
+ always @(posedge i_sys_clk or negedge i_rst_n) begin
+ if (!i_rst_n) begin
+ for (i = 0; i < REG_COUNT; i = i + 1) begin
+ regtable[i] <= 24'h0;
+ end
+ regtable[0] <= IDENT;
+ regtable[1] <= STATE_INIT;
+
+ rvalid_flag <= 1'b0;
+ busy_flag <= 1'b0;
+ err_flag <= 1'b0;
+ state <= IDLE;
+ end
+ else begin
+ case (state)
+ IDLE: begin
+ rvalid_flag <= 1'b0;
+ err_flag <= 1'b0;
+
+ // Priority Check: Did we crash/reset while EXEC bit was still 1?
+ if (exec_bit == 1'b1) begin
+ state <= EXEC_ACK;
+ busy_flag <= 1'b1;
+ end
+ else if (i_wr_req == 1'b1) begin
+ busy_flag <= 1'b1;
+ state <= BUSY;
+
+ // Addr Sanity Check
+ if ((i_wr && (i_addr == 'd0 || i_addr >= REG_COUNT)) ||
+ (!i_wr && (i_addr >= REG_COUNT)))
+ begin
+ err_flag <= 1'b1;
+ end
+ end
+ else begin
+ busy_flag <= 1'b0;
+ end
+ end
+
+ BUSY: begin
+ if (err_flag) begin
+ state <= IDLE;
+ end
+ else begin
+ if (i_wr == 1'b1) begin // --- WRITE ---
+ if (exec_bit == 1'b1) begin
+ // Cannot write if Controller is already running
+ err_flag <= 1'b1;
+ state <= IDLE;
+ end
+ else begin
+ regtable[i_addr] <= i_wdata;
+
+ // Check if this write is a "Start Command"
+ if (i_addr == 7'd1 && i_wdata[0] == 1'b1) begin
+ // Go to Handshake Start
+ state <= EXEC_ACK;
+ end else begin
+ state <= IDLE;
+ end
+ end
+ end
+ else begin // --- READ ---
+ rdata_reg <= regtable[i_addr];
+ rvalid_flag <= 1'b1;
+ state <= IDLE;
+ end
+ end
+ end
+
+ // --- EXEC PHASE 1: ACK ---
+ // Wait for Controller to register the command and pull 'done' LOW (Busy)
+ EXEC_ACK: begin
+ busy_flag <= 1'b1;
+ if (i_con_done == 1'b0) begin
+ state <= EXEC_WAIT;
+ end
+ // Optional: Timeout counter here to prevent hanging if Controller is dead
+ end
+
+ // --- EXEC PHASE 2: WAIT ---
+ // Now wait for Controller to finish and pull 'done' HIGH (Idle/Ready)
+ EXEC_WAIT: begin
+ busy_flag <= 1'b1;
+ if (i_con_done == 1'b1) begin
+ // 1. Clear the Exec bit (Auto-Clear)
+ // 2. Set the Ready bit (Bit 23) if you wish
+ regtable[1] <= {1'b1, regtable[1][22:1], 1'b0};
+
+ busy_flag <= 1'b0;
+ state <= IDLE;
+ end
+ end
+
+ default: state <= IDLE;
+ endcase
+ end
+ end
+
+ assign o_rvalid = rvalid_flag;
+ assign o_rdata = rdata_reg;
+ assign o_busy = busy_flag;
+ assign o_err = err_flag;
+
+ // Output the control bit to the controller
+ // This stays HIGH during both EXEC_ACK and EXEC_WAIT
+ assign o_exec = exec_bit;
+
+ assign o_freq1 = regtable[2];
+ assign o_freq2 = regtable[3];
+ assign o_freq3 = regtable[4];
+ assign o_freq4 = regtable[5];
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD1/RelayConTop.lst b/2.FW/CPLD1/RelayConTop.lst
new file mode 100644
index 0000000..0c83011
--- /dev/null
+++ b/2.FW/CPLD1/RelayConTop.lst
@@ -0,0 +1,4 @@
+"/home/ly0kos/work/prj/New_CalBoard/2.FW/CPLD1/RelayConTop.v=work,Verilog_2001"
+"/home/ly0kos/work/prj/New_CalBoard/2.FW/CPLD1/BUS_Con.v=work,Verilog_2001"
+"/home/ly0kos/work/prj/New_CalBoard/2.FW/CPLD1/Reg_file.v=work,Verilog_2001"
+"/home/ly0kos/work/prj/New_CalBoard/2.FW/CPLD1/CPLD_Freq_Con.v=work,Verilog_2001"
diff --git a/2.FW/CPLD1/RelayConTop.naf b/2.FW/CPLD1/RelayConTop.naf
new file mode 100644
index 0000000..c20f2a5
--- /dev/null
+++ b/2.FW/CPLD1/RelayConTop.naf
@@ -0,0 +1,165 @@
+i_sys_clk i
+i_rst_n i
+i_sclk i
+i_mosi i
+i_cs i
+o_miso o
+o_rvalid o
+i_rready i
+i_wvalid i
+o_wready o
+o_err o
+o_con_done o
+o_DMM_EN[18] o
+o_DMM_EN[17] o
+o_DMM_EN[16] o
+o_DMM_EN[15] o
+o_DMM_EN[14] o
+o_DMM_EN[13] o
+o_DMM_EN[12] o
+o_DMM_EN[11] o
+o_DMM_EN[10] o
+o_DMM_EN[9] o
+o_DMM_EN[8] o
+o_DMM_EN[7] o
+o_DMM_EN[6] o
+o_DMM_EN[5] o
+o_DMM_EN[4] o
+o_DMM_EN[3] o
+o_DMM_EN[2] o
+o_DMM_EN[1] o
+o_DMM_EN[0] o
+o_IO_RC1 o
+o_RC_T27 o
+o_RC_T28 o
+o_RC_T29 o
+o_RC_T30 o
+o_RC_T31 o
+o_OC_1[31] o
+o_OC_1[30] o
+o_OC_1[29] o
+o_OC_1[28] o
+o_OC_1[27] o
+o_OC_1[26] o
+o_OC_1[25] o
+o_OC_1[24] o
+o_OC_1[23] o
+o_OC_1[22] o
+o_OC_1[21] o
+o_OC_1[20] o
+o_OC_1[19] o
+o_OC_1[18] o
+o_OC_1[17] o
+o_OC_1[16] o
+o_OC_1[15] o
+o_OC_1[14] o
+o_OC_1[13] o
+o_OC_1[12] o
+o_OC_1[11] o
+o_OC_1[10] o
+o_OC_1[9] o
+o_OC_1[8] o
+o_OC_1[7] o
+o_OC_1[6] o
+o_OC_1[5] o
+o_OC_1[4] o
+o_OC_1[3] o
+o_OC_1[2] o
+o_OC_1[1] o
+o_OC_1[0] o
+o_OC_2[31] o
+o_OC_2[30] o
+o_OC_2[29] o
+o_OC_2[28] o
+o_OC_2[27] o
+o_OC_2[26] o
+o_OC_2[25] o
+o_OC_2[24] o
+o_OC_2[23] o
+o_OC_2[22] o
+o_OC_2[21] o
+o_OC_2[20] o
+o_OC_2[19] o
+o_OC_2[18] o
+o_OC_2[17] o
+o_OC_2[16] o
+o_OC_2[15] o
+o_OC_2[14] o
+o_OC_2[13] o
+o_OC_2[12] o
+o_OC_2[11] o
+o_OC_2[10] o
+o_OC_2[9] o
+o_OC_2[8] o
+o_OC_2[7] o
+o_OC_2[6] o
+o_OC_2[5] o
+o_OC_2[4] o
+o_OC_2[3] o
+o_OC_2[2] o
+o_OC_2[1] o
+o_OC_2[0] o
+o_OC_3[31] o
+o_OC_3[30] o
+o_OC_3[29] o
+o_OC_3[28] o
+o_OC_3[27] o
+o_OC_3[26] o
+o_OC_3[25] o
+o_OC_3[24] o
+o_OC_3[23] o
+o_OC_3[22] o
+o_OC_3[21] o
+o_OC_3[20] o
+o_OC_3[19] o
+o_OC_3[18] o
+o_OC_3[17] o
+o_OC_3[16] o
+o_OC_3[15] o
+o_OC_3[14] o
+o_OC_3[13] o
+o_OC_3[12] o
+o_OC_3[11] o
+o_OC_3[10] o
+o_OC_3[9] o
+o_OC_3[8] o
+o_OC_3[7] o
+o_OC_3[6] o
+o_OC_3[5] o
+o_OC_3[4] o
+o_OC_3[3] o
+o_OC_3[2] o
+o_OC_3[1] o
+o_OC_3[0] o
+o_OC_4[31] o
+o_OC_4[30] o
+o_OC_4[29] o
+o_OC_4[28] o
+o_OC_4[27] o
+o_OC_4[26] o
+o_OC_4[25] o
+o_OC_4[24] o
+o_OC_4[23] o
+o_OC_4[22] o
+o_OC_4[21] o
+o_OC_4[20] o
+o_OC_4[19] o
+o_OC_4[18] o
+o_OC_4[17] o
+o_OC_4[16] o
+o_OC_4[15] o
+o_OC_4[14] o
+o_OC_4[13] o
+o_OC_4[12] o
+o_OC_4[11] o
+o_OC_4[10] o
+o_OC_4[9] o
+o_OC_4[8] o
+o_OC_4[7] o
+o_OC_4[6] o
+o_OC_4[5] o
+o_OC_4[4] o
+o_OC_4[3] o
+o_OC_4[2] o
+o_OC_4[1] o
+o_OC_4[0] o
diff --git a/2.FW/CPLD1/RelayConTop.sym b/2.FW/CPLD1/RelayConTop.sym
new file mode 100644
index 0000000..07bc9d0
Binary files /dev/null and b/2.FW/CPLD1/RelayConTop.sym differ
diff --git a/2.FW/CPLD1/RelayConTop.tfi b/2.FW/CPLD1/RelayConTop.tfi
new file mode 100644
index 0000000..e7a4823
--- /dev/null
+++ b/2.FW/CPLD1/RelayConTop.tfi
@@ -0,0 +1,103 @@
+
+
+// TOOL: vlog2tf
+// DATE: Fri May 15 17:23:34 2026
+
+// TITLE: Lattice Semiconductor Corporation
+// MODULE: RelayConTop
+// DESIGN: RelayConTop
+// FILENAME: RelayConTop.tfi
+// PROJECT: NewExtIns_CPLD1
+// VERSION: 2.0
+// NOTE: DO NOT EDIT THIS FILE
+//
+// This file is generated by the Verilog Test Fixture Declarations process and
+// contains an I/O and instance declarations of the Verilog source file
+// you selected from the Sources in Project list.
+// Notes:
+// 1) This include file (.tfi) should be referenced by your text fixture using
+// the `include compile directive using the syntax: `include ".tfi"
+// 2) If your design I/O changes, rerun the process to obtain new I/O and
+// instance declarations.
+// 3) Verilog simulations will produce errors if there are Lattice FPGA library
+// elements in your design that require the instantiation of GSR, PUR, and TSALL
+// and they are not present in the test fixture. For more information see the
+// How To section of online help.
+
+
+
+// Inputs
+ reg i_sys_clk;
+ reg i_rst_n;
+ reg i_sclk;
+ reg i_mosi;
+ reg i_cs;
+ reg i_rready;
+ reg i_wvalid;
+
+
+// Outputs
+ wire o_miso;
+ wire o_rvalid;
+ wire o_wready;
+ wire o_err;
+ wire o_con_done;
+ wire [18:0] o_DMM_EN;
+ wire o_IO_RC1;
+ wire o_RC_T27;
+ wire o_RC_T28;
+ wire o_RC_T29;
+ wire o_RC_T30;
+ wire o_RC_T31;
+ wire [31:0] o_OC_1;
+ wire [31:0] o_OC_2;
+ wire [31:0] o_OC_3;
+ wire [31:0] o_OC_4;
+
+
+// Bidirs
+
+
+// Instantiate the UUT
+ RelayConTop UUT (
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+ .o_miso(o_miso),
+ .o_rvalid(o_rvalid),
+ .i_rready(i_rready),
+ .i_wvalid(i_wvalid),
+ .o_wready(o_wready),
+ .o_err(o_err),
+ .o_con_done(o_con_done),
+ .o_DMM_EN(o_DMM_EN),
+ .o_IO_RC1(o_IO_RC1),
+ .o_RC_T27(o_RC_T27),
+ .o_RC_T28(o_RC_T28),
+ .o_RC_T29(o_RC_T29),
+ .o_RC_T30(o_RC_T30),
+ .o_RC_T31(o_RC_T31),
+ .o_OC_1(o_OC_1),
+ .o_OC_2(o_OC_2),
+ .o_OC_3(o_OC_3),
+ .o_OC_4(o_OC_4)
+ );
+
+
+// Initialize Inputs
+`ifdef auto_init
+
+ initial begin
+ i_sys_clk = 0;
+ i_rst_n = 0;
+ i_sclk = 0;
+ i_mosi = 0;
+ i_cs = 0;
+ i_rready = 0;
+ i_wvalid = 0;
+ end
+
+`endif
+
diff --git a/2.FW/CPLD1/RelayConTop.v b/2.FW/CPLD1/RelayConTop.v
new file mode 100644
index 0000000..b5b9d3d
--- /dev/null
+++ b/2.FW/CPLD1/RelayConTop.v
@@ -0,0 +1,139 @@
+module RelayConTop (
+ input i_sys_clk,
+ input i_rst_n,
+
+ input i_sclk,
+ input i_mosi,
+ input i_cs,
+ output o_miso,
+ output o_rvalid,
+ input i_rready,
+ input i_wvalid,
+ output o_wready,
+ output o_err,
+ output o_con_done,
+ output [18:0]o_DMM_EN,
+ output o_IO_RC1,
+ output o_RC_T27,
+ output o_RC_T28,
+ output o_RC_T29,
+ output o_RC_T30,
+ output o_RC_T31,
+ output [31:0]o_OC_1,
+ output [31:0]o_OC_2,
+ output [31:0]o_OC_3,
+ output [31:0]o_OC_4
+
+);
+ wire [3:0]OC_x01;
+ wire [3:0]OC_x17;
+ wire [4:0]RC_Tx;
+
+ wire [18:0]DMM_EN;
+ wire IO_RC1;
+
+
+ wire [23:0]r_data ;
+ wire [23:0]w_data ;
+ wire [6:0]reg_addr ;
+
+ wire cmd_valid;
+ wire reg_busy;
+ wire wr_flag; //1=write,0=read
+ wire bus_err_flag;
+ wire reg_err_flag;
+ wire cpld_err_flag;
+
+ wire con_exec;
+ wire [23:0]freq1_relay ;
+ wire [23:0]freq2_relay ;
+ wire [23:0]freq3_relay ;
+ wire [23:0]freq4_relay ;
+ wire con_rvalid;
+
+ wire con_done;
+
+ BUS_Con BUS_Con_1(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+ .i_rvalid(con_rvalid),
+ .i_wvalid(i_wvalid),
+ .i_reg_busy(reg_busy),
+ .i_rdata(r_data),
+ .o_cmd_valid(cmd_vaild),
+ .o_wr(wr_flag),
+ .o_miso(o_miso),
+ .o_rvalid(o_rvalid),
+ .o_wready(o_wready),
+ .o_data(w_data),
+ .o_addr(reg_addr),
+ .o_err(bus_err_flag)
+ );
+
+ Reg_file CPLD_Reg_1(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_wr_req(cmd_vaild),
+ .i_wr(wr_flag),
+ .i_addr(reg_addr),
+ .i_wdata(w_data),
+ .i_con_done(con_done), //Controller Exec Done
+ .o_freq1(freq1_relay), //Freq_Slot1
+ .o_freq2(freq2_relay), //Freq_Slot2
+ .o_freq3(freq3_relay), //Freq_Slot3
+ .o_freq4(freq4_relay), //Freq_Slot4
+ .o_rvalid(con_rvalid),
+ .o_rdata(r_data),
+ .o_exec(con_exec), //Exec cmd
+ .o_busy(reg_busy),
+ .o_err(reg_err_flag)
+ );
+
+ CPLD_Con CPLD_Con_1(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_con_exec(con_exec),
+ .i_freq_relay1(freq1_relay),
+ .i_freq_relay2(freq2_relay),
+ .i_freq_relay3(freq3_relay),
+ .i_freq_relay4(freq4_relay),
+ .o_con_done(con_done),
+ .o_OC_x01(OC_x01),
+ .o_OC_x17(OC_x17),
+ .o_RC_Tx(RC_Tx),
+ .o_DMM_EN(DMM_EN),
+ .o_IO_RC1(IO_RC1),
+ .o_err(cpld_err_flag)
+ );
+
+ assign o_con_done = con_done;
+ //assign o_OC_x01 = OC_x01;
+ assign o_OC_1[0] = OC_x01[0];
+ assign o_OC_2[0] = OC_x01[1];
+ assign o_OC_3[0] = OC_x01[2];
+ assign o_OC_4[0] = OC_x01[3];
+
+ //assign o_OC_x17 = OC_x17;
+ assign o_OC_1[16] = OC_x17[0];
+ assign o_OC_2[16] = OC_x17[1];
+ assign o_OC_3[16] = OC_x17[2];
+ assign o_OC_4[16] = OC_x17[3];
+
+
+
+ assign o_DMM_EN = DMM_EN;
+ assign o_IO_RC1 = IO_RC1;
+
+ assign o_RC_T27 = RC_Tx[4];
+ assign o_RC_T28 = RC_Tx[3];
+ assign o_RC_T29 = RC_Tx[2];
+ assign o_RC_T30 = RC_Tx[1];
+ assign o_RC_T31 = RC_Tx[0];
+
+
+ assign o_err = bus_err_flag || reg_err_flag ||cpld_err_flag;
+
+endmodule
diff --git a/2.FW/CPLD1/RelayConTop_tf.v b/2.FW/CPLD1/RelayConTop_tf.v
new file mode 100644
index 0000000..de3022a
--- /dev/null
+++ b/2.FW/CPLD1/RelayConTop_tf.v
@@ -0,0 +1,93 @@
+
+
+// TOOL: vlog2tf
+// DATE: Fri May 15 17:23:27 2026
+
+// TITLE: Lattice Semiconductor Corporation
+// MODULE: RelayConTop
+// DESIGN: RelayConTop
+// FILENAME: RelayConTop_tf.v
+// PROJECT: NewExtIns_CPLD1
+// VERSION: 2.0
+// This file is auto generated by Diamond
+
+
+`timescale 1 ns / 1 ps
+
+// Define Module for Test Fixture
+module RelayConTop_tf();
+
+// Inputs
+ reg i_sys_clk;
+ reg i_rst_n;
+ reg i_sclk;
+ reg i_mosi;
+ reg i_cs;
+ reg i_rready;
+ reg i_wvalid;
+
+
+// Outputs
+ wire o_miso;
+ wire o_rvalid;
+ wire o_wready;
+ wire o_err;
+ wire o_con_done;
+ wire [18:0] o_DMM_EN;
+ wire o_IO_RC1;
+ wire o_RC_T27;
+ wire o_RC_T28;
+ wire o_RC_T29;
+ wire o_RC_T30;
+ wire o_RC_T31;
+ wire [31:0] o_OC_1;
+ wire [31:0] o_OC_2;
+ wire [31:0] o_OC_3;
+ wire [31:0] o_OC_4;
+
+
+// Bidirs
+
+
+// Instantiate the UUT
+// Please check and add your parameters manually
+ RelayConTop UUT (
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+ .o_miso(o_miso),
+ .o_rvalid(o_rvalid),
+ .i_rready(i_rready),
+ .i_wvalid(i_wvalid),
+ .o_wready(o_wready),
+ .o_err(o_err),
+ .o_con_done(o_con_done),
+ .o_DMM_EN(o_DMM_EN),
+ .o_IO_RC1(o_IO_RC1),
+ .o_RC_T27(o_RC_T27),
+ .o_RC_T28(o_RC_T28),
+ .o_RC_T29(o_RC_T29),
+ .o_RC_T30(o_RC_T30),
+ .o_RC_T31(o_RC_T31),
+ .o_OC_1(o_OC_1),
+ .o_OC_2(o_OC_2),
+ .o_OC_3(o_OC_3),
+ .o_OC_4(o_OC_4)
+ );
+
+
+// Initialize Inputs
+// You can add your stimulus here
+ initial begin
+ i_sys_clk = 0;
+ i_rst_n = 0;
+ i_sclk = 0;
+ i_mosi = 0;
+ i_cs = 0;
+ i_rready = 0;
+ i_wvalid = 0;
+ end
+
+endmodule // RelayConTop_tf
\ No newline at end of file
diff --git a/2.FW/CPLD1/piodrc.cfg b/2.FW/CPLD1/piodrc.cfg
new file mode 100644
index 0000000..e69de29
diff --git a/2.FW/CPLD1/tb_RelayConTop.sv b/2.FW/CPLD1/tb_RelayConTop.sv
new file mode 100644
index 0000000..e53f764
--- /dev/null
+++ b/2.FW/CPLD1/tb_RelayConTop.sv
@@ -0,0 +1,310 @@
+`timescale 1ns/1ps
+
+module tb_RelayConTop;
+
+ // 时钟和复位
+ reg i_sys_clk;
+ reg i_rst_n;
+
+ // SPI接口
+ reg i_sclk;
+ reg i_mosi;
+ reg i_cs;
+// wire o_miso;
+
+ // 流控制接口
+// wire o_rvaild;
+// reg i_rready;
+// reg i_wvaild;
+// wire o_wready;
+ wire o_err;
+
+ // 继电器控制输出
+ wire [7:0] o_RC_F;
+ wire [15:0] o_RC_S;
+ wire [31:0] o_RC_T;
+
+ // 测试变量
+ reg [31:0] spi_data;
+ integer test_pass;
+ integer test_fail;
+
+ // 实例化被测模块
+ RelayConTop DUT (
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+// .o_miso(o_miso),
+// .o_rvaild(o_rvaild),
+// .i_rready(i_rready),
+// .i_wvaild(i_wvaild),
+// .o_wready(o_wready),
+ .o_err(o_err),
+ .o_RC_F(o_RC_F),
+ .o_RC_S(o_RC_S),
+ .o_RC_T(o_RC_T)
+ );
+
+ // 时钟生成
+ initial begin
+ i_sys_clk = 0;
+ forever #5 i_sys_clk = ~i_sys_clk; // 20MHz系统时钟
+ end
+
+ // SPI时钟生成(比系统时钟慢)
+ initial begin
+ i_sclk = 0;
+ forever #50 i_sclk = ~i_sclk; // 2MHz SPI时钟
+ end
+
+ // 主测试流程
+ initial begin
+ // 初始化
+ initialize();
+
+ // 测试计数器
+ test_pass = 0;
+ test_fail = 0;
+
+ $display("=== CPLD2 Controller Test Start ===");
+
+ // 测试1: 复位后寄存器读取
+ test_reset_registers();
+
+
+ // 测试2: 寄存器写入和读取
+ test_register_write_read();
+
+ // 测试3: EXEC命令执行测试
+ test_exec_command();
+
+ // 测试4: 错误条件测试
+ test_error_conditions();
+
+ // 测试5: SPI连续传输测试
+ test_spi_continuous();
+
+ // 测试6: 边界条件测试
+ test_boundary_conditions();
+
+ // 总结
+ $display("=== Test Done ===");
+ $display("PASS: %0d", test_pass);
+ $display("Failed: %0d", test_fail);
+
+ if (test_fail == 0) begin
+ $display("*** ALL TEST PASSED! ***");
+ end else begin
+ $display("*** TEST FAILED FOUND!! CHECK DESIGN ***");
+ end
+
+ #1000 $finish;
+ end
+
+ // 初始化任务
+ task initialize;
+ begin
+ i_rst_n = 1;
+ i_cs = 1;
+ i_mosi = 0;
+ #100;
+ i_rst_n = 0;
+ #200;
+ i_rst_n = 1;
+ i_cs = 1;
+ $display("Initialize DONE!");
+ end
+ endtask
+
+ // SPI发送任务
+ task spi_send;
+ input [31:0] data;
+ integer i;
+ begin
+ #50;
+ i_cs = 0; // 片选有效
+
+ for (i = 31; i >= 0 ; i--) begin
+ #50; // 在SCLK上升沿前设置数据
+ i_mosi = data[i];
+ #50; // 等待SCLK上升沿
+ end
+ #50
+ i_cs = 1; // 片选无效
+ #200;
+ end
+ endtask
+
+ // 测试1: 复位后寄存器读取
+ task test_reset_registers;
+ begin
+ $display("--- TEST1: REG READ AFTER RST ---");
+ // 读取芯片ID寄存器 (地址0)
+ spi_data = {1'b1,23'h0, 1'b0,7'h0}; // 读操作,地址0,TEST
+ spi_send(spi_data);
+
+ // 检查返回值(应该在MISO上看到0x400000)
+ #1000;
+ check_result(1, "CPLD READ ID");
+ end
+ endtask
+
+ // 测试2: 寄存器写入和读取
+ task test_register_write_read;
+ begin
+ $display("--- TEST2: REG READ & WRITE ---");
+
+ // 写入频率槽1寄存器 (地址2)
+ spi_data = {24'h123456,1'b1,7'h2}; // 写操作,地址2,数据0x123456
+ spi_send(spi_data);
+ #500;
+
+ // 读取频率槽1寄存器验证
+ spi_data = {24'h0, 1'b0, 7'h2}; // 读操作,地址2
+ spi_send(spi_data);
+ #500;
+
+ check_result(1, "REG READ & WRITE");
+ end
+ endtask
+
+ // 测试3: EXEC命令执行测试
+ task test_exec_command;
+ begin
+ $display("--- TEST3: EXEC TEST ---");
+
+ // 设置EXEC位 (地址1的bit0)
+ spi_data = {24'h000001, 1'b1, 7'h1}; // 写操作,地址1,设置EXEC位
+ spi_send(spi_data);
+ #1000;
+
+ check_result(1, "EXEC TEST");
+ end
+ endtask
+
+ // 测试4: 错误条件测试
+ task test_error_conditions;
+ begin
+ $display("--- 测试4: ERR TEST ---");
+
+ // 测试4.1: 写入只读寄存器 (地址0)
+ spi_data = {24'hDEADBE,1'b1, 7'h0 }; // 尝试写入只读寄存器
+ spi_send(spi_data);
+ #500;
+
+ // 测试4.2: 访问超出范围的地址
+ spi_data = {24'h0, 1'b0, 7'h20}; // 读取地址32(超出范围)
+ spi_send(spi_data);
+ #500;
+
+ check_result(1, "ERR TEST");
+ end
+ endtask
+
+ // 测试5: SPI连续传输测试
+ task test_spi_continuous;
+ begin
+ $display("--- 测试5: SPI BATCH READ&WRITE ---");
+
+ // 连续写入多个寄存器
+ spi_data = {24'h111111, 7'h2, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h222222, 7'h3, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h333333, 7'h4, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ // 连续读取验证
+ spi_data = {24'h0, 7'h2, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h0, 7'h3, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h0, 7'h4, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ check_result(1, "SPI BATCH READ&WRITE");
+ end
+ endtask
+
+ // 测试6: 边界条件测试
+ task test_boundary_conditions;
+ begin
+ $display("--- TEST6: EDGE CASE TEST ---");
+
+ // 测试6.1: 复位期间的SPI访问
+ i_rst_n = 0;
+ spi_data = {24'h0, 7'h1, 1'b0};
+ spi_send(spi_data);
+ #200;
+ i_rst_n = 1;
+ #500;
+
+ // 测试6.2: CS信号异常
+ i_cs = 0;
+ #50;
+ i_cs = 1; // 短暂CS脉冲
+ #50;
+ i_cs = 0;
+ #1000;
+ i_cs = 1;
+ #500;
+
+ check_result(1, "EDGE CASE TEST");
+ end
+ endtask
+
+ // 结果检查任务
+ task check_result;
+ input expected;
+ input [120:1] test_name; // 字符数组存储测试名称
+ begin
+ if (expected) begin
+ test_pass = test_pass + 1;
+ $display("TEST %s - PASSED", test_name);
+ end else begin
+ test_fail = test_fail + 1;
+ $display("TEST %s - FAILED", test_name);
+ end
+ end
+ endtask
+
+ /*
+ // 监控关键信号
+ initial begin
+ $display("TIME | CS | SCLK | MOSI | MISO | ERR | RC_CON");
+ $display("-----|----|------|------|------|------|--------");
+ forever begin
+ #1000;
+ $display("%4t | %b | %b | %b | %b | %b | F:%h S:%h T:%h",
+ $time, i_cs, i_sclk, i_mosi, o_miso, o_err,
+ o_RC_F, o_RC_S, o_RC_T);
+ end
+ end
+ */
+
+ // VCD文件生成(用于波形查看)
+ initial begin
+ $dumpfile("relay_con_top.vcd");
+ $dumpvars(0, tb_RelayConTop);
+ end
+
+ // 超时保护
+ initial begin
+ #5000000; // 5ms超时
+ $display("!!! TEST TIMEOUT !!!");
+ $finish;
+ end
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD1/tb_RelayConTop/source_files.lst b/2.FW/CPLD1/tb_RelayConTop/source_files.lst
new file mode 100644
index 0000000..8390a54
--- /dev/null
+++ b/2.FW/CPLD1/tb_RelayConTop/source_files.lst
@@ -0,0 +1,5 @@
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD1/CPLD_Freq_Con.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD1/Reg_file.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD1/BUS_Con.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD1/RelayConTop.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD1/tb_RelayConTop.sv=work,"
diff --git a/2.FW/CPLD2/.gitignore b/2.FW/CPLD2/.gitignore
new file mode 100644
index 0000000..bd935a3
--- /dev/null
+++ b/2.FW/CPLD2/.gitignore
@@ -0,0 +1,3 @@
+# Lattice Diamond 实现输出目录
+# 根目录 .gitignore 已覆盖大部分 pattern,此处仅确保 impl1/ 被忽略
+impl1/
diff --git a/2.FW/CPLD2/.run_manager.ini b/2.FW/CPLD2/.run_manager.ini
new file mode 100644
index 0000000..0e74f28
--- /dev/null
+++ b/2.FW/CPLD2/.run_manager.ini
@@ -0,0 +1,9 @@
+[Runmanager]
+Geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x1!\0\0\0\xe1\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0)
+windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x6/\0\0\x2\x81\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x1\0\0\0\0\0\0\0\x1\xff\xff\xff\xff\x3\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
+headerState=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x16\0\xe0?\0\0\0\t\0\0\0\x10\0\0\0\x64\0\0\0\xf\0\0\0\x64\0\0\0\xe\0\0\0\x64\0\0\0\r\0\0\0\x64\0\0\0\x15\0\0\0\x64\0\0\0\x14\0\0\0\x64\0\0\0\x13\0\0\0\x64\0\0\0\x12\0\0\0\x64\0\0\0\x11\0\0\0\x64\0\0\x6+\0\0\0\x16\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\0#\0\0\0\x1\0\0\0\x2\0\0\x4L\0\0\0\v\0\0\0\0\0\0\x1\xbc\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\t\0\0\0\0)
+
+[impl1%3CStrategy1%3E]
+isChecked=true
+isHidden=false
+isExpanded=true
diff --git a/2.FW/CPLD2/.setting.ini b/2.FW/CPLD2/.setting.ini
new file mode 100644
index 0000000..444c6f1
--- /dev/null
+++ b/2.FW/CPLD2/.setting.ini
@@ -0,0 +1,4 @@
+[General]
+Export.auto_tasks=Bitgen, Jedecgen
+Map.auto_tasks=MapTrace
+AutoAssign=false
diff --git a/2.FW/CPLD2/.spread_sheet.ini b/2.FW/CPLD2/.spread_sheet.ini
new file mode 100644
index 0000000..6c511f4
--- /dev/null
+++ b/2.FW/CPLD2/.spread_sheet.ini
@@ -0,0 +1,3 @@
+[General]
+COLUMN_POS_INFO_NAME_-1_0=Prioritize
+COLUMN_POS_INFO_NAME_-1_1=PIO Register
diff --git a/2.FW/CPLD2/.spreadsheet_view.ini b/2.FW/CPLD2/.spreadsheet_view.ini
new file mode 100644
index 0000000..276d124
--- /dev/null
+++ b/2.FW/CPLD2/.spreadsheet_view.ini
@@ -0,0 +1,76 @@
+[General]
+pin_sort_type=0
+pin_sort_ascending=true
+sig_sort_type=0
+sig_sort_ascending=true
+active_Sheet=Global Preferences
+
+[Port%20Assignments]
+Name="176,0"
+Group%20By="118,1"
+Pin="71,2"
+BANK="91,3"
+BANK_VCC="129,4"
+VREF="85,5"
+IO_TYPE="111,6"
+PULLMODE="133,7"
+DRIVE="92,8"
+SLEWRATE="129,9"
+CLAMP="99,10"
+OPENDRAIN="139,11"
+DIFFRESISTOR="160,12"
+DIFFDRIVE="127,13"
+HYSTERESIS="143,14"
+Outload%20%28pF%29="144,15"
+MaxSkew="120,16"
+Clock%20Load%20Only="172,17"
+SwitchingID="141,18"
+Ground%20plane%20PCB%20noise%20%28mV%29="274,19"
+Power%20plane%20PCB%20noise%20%28mV%29="266,20"
+SSO%20Allowance%28%25%29="189,21"
+sort_columns="Name,Ascending"
+
+[Pin%20Assignments]
+Pin="111,0"
+Pad%20Name="126,1"
+Dual%20Function="157,2"
+Polarity="108,3"
+BANK="0,4"
+BANK_VCC="129,5"
+IO_TYPE="111,6"
+Signal%20Name="144,7"
+Signal%20Type="137,8"
+sort_columns="Pin,Ascending"
+
+[Clock%20Resource]
+Clock%20Type="100,ELLIPSIS"
+Clock%20Name="405,ELLIPSIS"
+Selection="100,ELLIPSIS"
+
+[Global%20Preferences]
+Preference%20Name="230,ELLIPSIS"
+Preference%20Value="232,ELLIPSIS"
+
+[Cell%20Mapping]
+Type="100,ELLIPSIS"
+Name="100,ELLIPSIS"
+Din\Dout="100,ELLIPSIS"
+PIO%20Register="100,ELLIPSIS"
+
+[Route%20Priority]
+Type="100,ELLIPSIS"
+Name="100,ELLIPSIS"
+Prioritize="100,ELLIPSIS"
+
+[Timing%20Preferences]
+Preference%20Name="146,ELLIPSIS"
+Preference%20Value="143,ELLIPSIS"
+Preference%20Unit="1122,ELLIPSIS"
+
+[Group]
+Group%20Type\Name="153,ELLIPSIS"
+Value="53,ELLIPSIS"
+
+[Misc%20Preferences]
+Preference%20Name="146,ELLIPSIS"
+Preference%20Value="143,ELLIPSIS"
diff --git a/2.FW/CPLD2/BUS_Con.v b/2.FW/CPLD2/BUS_Con.v
new file mode 100644
index 0000000..8fe11fe
--- /dev/null
+++ b/2.FW/CPLD2/BUS_Con.v
@@ -0,0 +1,215 @@
+module BUS_Con (
+ input i_sys_clk,
+ input i_rst_n,
+
+ // SPI Interface
+ input i_sclk,
+ input i_mosi,
+ input i_cs,
+ output o_miso, // <-- MISO Logic added here
+
+ // Local Interface
+ output o_rvaild, // (Typo in original: o_rvalid)
+ input i_rvaild, // Valid signal from Backend (Data is ready)
+ input i_wvaild,
+ output o_wready,
+ input i_reg_busy,
+ input [23:0] i_rdata, // Data from Backend to send to Master
+ output o_wr,
+ output o_cmd_vaild,
+ output [23:0] o_data,
+ output [6:0] o_addr,
+ output o_err
+);
+
+ // --- 1. Synchronization ---
+ reg [1:0] cs_sync;
+ reg [1:0] sclk_sync;
+ reg [1:0] mosi_sync;
+
+ wire cs_active;
+ wire cs_rise;
+ wire sclk_rise; // For Sampling MOSI
+ wire sclk_fall; // For Shifting MISO
+ wire mosi_data;
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ cs_sync <= 2'b11;
+ sclk_sync <= 2'b00;
+ mosi_sync <= 2'b00;
+ end else begin
+ cs_sync <= {cs_sync[0], i_cs};
+ sclk_sync <= {sclk_sync[0], i_sclk};
+ mosi_sync <= {mosi_sync[0], i_mosi};
+ end
+ end
+
+ assign cs_active = ~cs_sync[1];
+ assign cs_rise = (!cs_sync[1] && cs_sync[0]);
+
+ // SPI Mode 0: Sample MOSI on Rising, Shift MISO on Falling
+ assign sclk_rise = (!sclk_sync[1] && sclk_sync[0]);
+ assign sclk_fall = (sclk_sync[1] && !sclk_sync[0]); // Logic for MISO
+ assign mosi_data = mosi_sync[1];
+
+ // --- 2. MOSI (Receive) Logic ---
+ reg [31:0] recv_reg;
+ reg [5:0] bit_cnt;
+ reg data_ready;
+ reg err_flag;
+ reg [1:0] state;
+ //
+ reg [31:0] tx_buffer; // Holds data waiting for the next CS Low
+ reg [31:0] miso_shift; // The actual shifter
+ // Output Registers
+ reg [6:0] addr_out;
+ reg [23:0] data_out;
+ reg wr_out;
+ reg cmd_valid_out;
+
+ //
+ localparam IDLE = 2'b00;
+ localparam CMD_SENT = 2'b01;
+ localparam WAIT_BUSY = 2'b10;
+ localparam DONE = 2'b11;
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ recv_reg <= 32'd0;
+ bit_cnt <= 6'd0;
+ data_ready <= 1'b0;
+ err_flag <= 1'b0;
+ end
+ else begin
+ data_ready <= 1'b0;
+
+ if (cs_active) begin
+ if (sclk_rise) begin
+ recv_reg <= {recv_reg[30:0], mosi_data};
+ bit_cnt <= bit_cnt + 1'b1;
+ end
+ else if (cs_rise) begin
+ if (bit_cnt == 6'd32) begin
+ data_ready <= 1'b1;
+ err_flag <= 1'b0;
+ bit_cnt <= 6'd0;
+ end
+ else if (bit_cnt != 0) begin
+ err_flag <= 1'b1;
+ bit_cnt <= 6'd0;
+ recv_reg <= 'd0;
+ end
+ end
+ end
+ if (state == DONE) begin
+ recv_reg <= 'd0;
+ end
+ end
+ end
+
+ // --- 3. MISO (Transmit) Logic ---
+ // Protocol: We shift out 32 bits.
+ // Format: [8 bit Status/Padding] + [24 bit i_rdata]
+
+
+ // Capture data from backend when valid
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ tx_buffer <= 32'd0;
+ end else begin
+ // If backend provides valid read data, store it.
+ // We pad the top 8 bits with Zeros (or you can put status flags here)
+ if (i_rvaild) begin
+ tx_buffer <= {8'h00, i_rdata};
+ end
+ end
+ end
+
+ // Shift data out
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ miso_shift <= 32'd0;
+ end else begin
+ if (!cs_active) begin
+ // Pre-load the shifter while CS is High
+ // This ensures Bit 31 is ready BEFORE the first clock edge
+ miso_shift <= tx_buffer;
+ end else begin
+ // Shift on Falling Edge (Master samples on Rising)
+ if (sclk_fall) begin
+ miso_shift <= {miso_shift[30:0], 1'b0};
+ end
+ end
+ end
+ end
+
+ // Tri-state MISO when CS is high (optional, usually good practice)
+ // If your board doesn't need tristate, just use: assign o_miso = miso_shift[31];
+ assign o_miso = (cs_active) ? miso_shift[31] : 1'bz;
+
+ // --- 4. Register Control FSM ---
+
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ state <= IDLE;
+ cmd_valid_out <= 1'b0;
+ addr_out <= 7'd0;
+ data_out <= 24'd0;
+ wr_out <= 1'b0;
+ end else begin
+ case (state)
+ IDLE: begin
+ if (data_ready) begin
+ addr_out <= recv_reg[30:24];
+ data_out <= recv_reg[23:0];
+ wr_out <= recv_reg[31];
+
+ if (!i_reg_busy) begin
+ cmd_valid_out <= 1'b1;
+ state <= CMD_SENT;
+ end else begin
+ state <= WAIT_BUSY;
+ end
+ end
+ end
+
+ WAIT_BUSY: begin
+ if (!i_reg_busy) begin
+ cmd_valid_out <= 1'b1;
+ state <= CMD_SENT;
+ end
+ end
+
+ CMD_SENT: begin
+ cmd_valid_out <= 1'b0;
+ state <= DONE;
+ end
+
+ DONE: begin
+ if (!i_reg_busy) begin
+ state <= IDLE;
+ addr_out <= 'd0;
+ data_out <= 'd0;
+ wr_out <= 'd0;
+ end
+ end
+ endcase
+ end
+ end
+
+ assign o_addr = addr_out;
+ assign o_data = data_out;
+ assign o_wr = wr_out;
+ assign o_cmd_vaild = cmd_valid_out;
+ assign o_err = err_flag;
+ assign o_wready = (state == IDLE);
+
+ // Pass through unused signal or hook it up if needed
+ assign o_rvaild = 1'b0;
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD2/CPLD_Con.v b/2.FW/CPLD2/CPLD_Con.v
new file mode 100644
index 0000000..701bc69
--- /dev/null
+++ b/2.FW/CPLD2/CPLD_Con.v
@@ -0,0 +1,192 @@
+module CPLD_Con (
+ input i_sys_clk,
+ input i_rst_n,
+ input i_con_exec,
+ input [23:0]i_freq_relay1,
+ input [23:0]i_freq_relay2,
+ input [23:0]i_freq_relay3,
+ input [23:0]i_freq_relay4,
+ output o_con_done,
+ output [7:0]o_RC_F, //Ref: Schematic
+ output [15:0]o_RC_S,
+ output [31:0]o_RC_T,
+ output [3:0] o_OC_x09,
+ output [3:0] o_OC_x25
+);
+
+ //Output Relay Reg
+ reg [3:0] OC_x09;
+ reg [3:0] OC_x25;
+
+ //Relay Reg
+ reg [7:0]relay_l1;
+ reg [15:0]relay_l2 ;
+ reg [31:0]relay_l3 ;
+
+ //Flags
+ reg exec_done_flag;
+ reg exec_flag;
+
+ reg [3:0]slot_exec_flag;
+ reg err_flag;
+
+ //Counter
+ reg [15:0]delay_cnt;
+
+ wire [8:0] freq_relay1 = i_freq_relay1[9:1];
+ wire [8:0] freq_relay2 = i_freq_relay2[9:1];
+ wire [8:0] freq_relay3 = i_freq_relay3[9:1];
+ wire [8:0] freq_relay4 = i_freq_relay4[9:1];
+
+ always @(posedge i_sys_clk) begin
+ if (i_rst_n == 1'b0) begin
+ delay_cnt <= 'd0;
+ end
+ else begin
+ if (exec_flag == 1'b1) begin
+ delay_cnt <= delay_cnt + 1'd1;
+ end
+ else begin
+ delay_cnt <= 'd0;
+ end
+ end
+ end
+
+ always @(posedge i_sys_clk) begin
+ if (i_rst_n == 1'b0) begin
+ relay_l1 <= 'd0;
+ relay_l2 <= 'd0;
+ relay_l3 <= 'd0;
+ exec_flag <= 1'b0;
+ exec_done_flag <= 1'b1;
+ slot_exec_flag <= 'd0;
+ err_flag <= 'd0;
+ end
+ else begin
+ if ((i_con_exec == 1'b1) & (exec_flag == 1'b0)) begin
+ exec_done_flag <= 'd0;
+ exec_flag <= 1'b1;
+ //To DO: More Sanity Check?
+ // Add the bits together. Verilog handles the width expansion automatically for the comparison.
+ if ( (i_freq_relay1[0] + i_freq_relay2[0] + i_freq_relay3[0] + i_freq_relay4[0]) > 2'd1 ) begin
+ err_flag <= 1'b1;
+ end
+ else begin
+ slot_exec_flag[0] <= i_freq_relay1[0];
+ slot_exec_flag[1] <= i_freq_relay2[0];
+ slot_exec_flag[2] <= i_freq_relay3[0];
+ slot_exec_flag[3] <= i_freq_relay4[0];
+ end
+ end
+ else if (exec_flag == 1'b1) begin
+ //Output Relay
+ case (slot_exec_flag)
+ 4'b0001: begin
+ relay_l1 <= {'d0,i_freq_relay1[22],i_freq_relay1[23]};
+ if (delay_cnt == 'd500) begin
+ relay_l2 <= {'d0,i_freq_relay1[18],i_freq_relay1[19],i_freq_relay1[20],i_freq_relay1[21]};
+ end
+ else if (delay_cnt == 'd1000) begin
+ relay_l3 <= {'d0,i_freq_relay1[10],i_freq_relay1[11],i_freq_relay1[12],i_freq_relay1[13],i_freq_relay1[14],i_freq_relay1[15],i_freq_relay1[16],i_freq_relay1[17]};
+ end
+ else if (delay_cnt == 'd1080) begin
+ exec_flag <= 'd0;
+ exec_done_flag <= 1'b1;
+ end
+ if ((freq_relay1 > 64) & (freq_relay1 < 73)) begin
+ OC_x09 <= 4'b0001;
+ end
+ else if ((freq_relay1 > 192) & (freq_relay1 < 201)) begin
+ OC_x25 <= 4'b0001;
+ end
+ else begin
+ OC_x09 <= 'd0;
+ OC_x25 <= 'd0;
+ end
+ end
+ 4'b0010: begin
+ relay_l1 <= {4'd0,i_freq_relay2[22],i_freq_relay2[23],2'd0};
+ if (delay_cnt == 'd500) begin
+ relay_l2 <= {8'd0,i_freq_relay2[18],i_freq_relay2[19],i_freq_relay2[20],i_freq_relay2[21],4'd0};
+ end
+ else if (delay_cnt == 'd1000) begin
+ relay_l3 <= {16'd0,i_freq_relay2[10],i_freq_relay2[11],i_freq_relay2[12],i_freq_relay2[13],i_freq_relay2[14],i_freq_relay2[15],i_freq_relay2[16],i_freq_relay2[17],8'd0};
+ end
+ else if (delay_cnt == 'd1080) begin
+ exec_flag <= 'd0;
+ exec_done_flag <= 1'b1;
+ end
+ if ((freq_relay2 > 64) & (freq_relay2 < 73)) begin
+ OC_x09 <= 4'b0010;
+ end
+ else if ((freq_relay2 > 192) & (freq_relay2 < 201)) begin
+ OC_x25 <= 4'b0010;
+ end
+ else begin
+ OC_x09 <= 'd0;
+ OC_x25 <= 'd0;
+ end
+ end
+ 4'b0100: begin
+ relay_l1 <= {2'd0,i_freq_relay3[22],i_freq_relay3[23],4'd0};
+ if (delay_cnt == 'd500) begin
+ relay_l2 <= {4'd0,i_freq_relay3[18],i_freq_relay3[19],i_freq_relay3[20],i_freq_relay3[21],8'd0};
+ end
+ else if (delay_cnt == 'd1000) begin
+ relay_l3 <= {8'd0,i_freq_relay3[12],i_freq_relay3[13],i_freq_relay3[10],i_freq_relay3[11],i_freq_relay3[16],i_freq_relay3[17],i_freq_relay3[14],i_freq_relay3[15],16'd0};
+ end
+ else if (delay_cnt == 'd1080) begin
+ exec_flag <= 'd0;
+ exec_done_flag <= 1'b1;
+ end
+ if ((freq_relay3 > 64) &(freq_relay3 <73)) begin
+ OC_x09 <= 4'b0100;
+ end
+ else if ((freq_relay3 > 192) & (freq_relay3 < 201)) begin
+ OC_x25 <= 4'b0100;
+ end
+ else begin
+ OC_x09 <= 'd0;
+ OC_x25 <= 'd0;
+ end
+ end
+ 4'b1000: begin
+ relay_l1 <= {i_freq_relay4[22],i_freq_relay4[23],6'd0};
+ if (delay_cnt == 'd500) begin
+ relay_l2 <= {i_freq_relay4[18],i_freq_relay4[19],i_freq_relay4[20],i_freq_relay4[21],12'd0};
+ end
+ else if (delay_cnt == 'd1000) begin
+ relay_l3 <= {i_freq_relay4[10],i_freq_relay4[11],i_freq_relay4[12],i_freq_relay4[13],i_freq_relay4[14],i_freq_relay4[15],i_freq_relay4[16],i_freq_relay4[17],24'd0};
+ end
+ else if (delay_cnt == 'd1080) begin
+ exec_flag <= 'd0;
+ exec_done_flag <= 1'b1;
+ end
+ if ((freq_relay4 > 64) & (freq_relay4 < 73)) begin
+ OC_x09 <= 4'b1000;
+ end
+ else if ((freq_relay4 > 192) & (freq_relay4 < 201)) begin
+ OC_x25 <= 4'b1000;
+ end
+ else begin
+ OC_x09 <= 'd0;
+ OC_x25 <= 'd0;
+ end
+ end
+ default: begin
+ OC_x09 <= 4'b0000;
+ OC_x25 <= 4'b0000;
+ end
+ endcase
+ end
+ end
+ end
+
+ assign o_RC_F = relay_l1;
+ assign o_RC_S = relay_l2;
+ assign o_RC_T = relay_l3;
+ assign o_con_done = exec_done_flag;
+ assign o_OC_x09 = OC_x09;
+ assign o_OC_x25 = OC_x25;
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD2/NewExtIns_CPLD2.ccl b/2.FW/CPLD2/NewExtIns_CPLD2.ccl
new file mode 100644
index 0000000..dcf391b
--- /dev/null
+++ b/2.FW/CPLD2/NewExtIns_CPLD2.ccl
@@ -0,0 +1 @@
+VERSION=20110520
diff --git a/2.FW/CPLD2/NewExtIns_CPLD2.ldf b/2.FW/CPLD2/NewExtIns_CPLD2.ldf
new file mode 100644
index 0000000..f192cb0
--- /dev/null
+++ b/2.FW/CPLD2/NewExtIns_CPLD2.ldf
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2.FW/CPLD2/NewExtIns_CPLD2.lpf b/2.FW/CPLD2/NewExtIns_CPLD2.lpf
new file mode 100644
index 0000000..f6391ed
--- /dev/null
+++ b/2.FW/CPLD2/NewExtIns_CPLD2.lpf
@@ -0,0 +1,322 @@
+rvl_alias "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+BLOCK RESETPATHS ;
+BLOCK ASYNCPATHS ;
+LOCATE COMP "i_sys_clk" SITE "B9" ;
+LOCATE COMP "i_rst_n" SITE "Y14" ;
+LOCATE COMP "i_sclk" SITE "AA16" ;
+LOCATE COMP "i_cs" SITE "Y15" ;
+LOCATE COMP "i_mosi" SITE "AB12" ;
+//LOCATE COMP "o_RC_T[26]" SITE "U13" ;
+//LOCATE COMP "o_RC_T[27]" SITE "U12" ;
+//LOCATE COMP "o_RC_T[28]" SITE "T12" ;
+//LOCATE COMP "o_RC_T[29]" SITE "T11" ;
+//LOCATE COMP "o_RC_T[30]" SITE "U11" ;
+//LOCATE COMP "o_RC_T[31]" SITE "V11" ;
+IOBUF PORT "i_cs" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_mosi" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_rst_n" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_sclk" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_miso" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=8 ;
+IOBUF PORT "o_wready" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_RC_F[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_F[1]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_sys_clk" DRIVE=NA IO_TYPE=LVCMOS33 SLEWRATE=NA PULLMODE=DOWN ;
+IOBUF PORT "o_RC_F[2]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_F[3]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_F[4]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_F[5]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_F[6]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_F[7]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[1]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[2]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[3]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[4]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[5]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[6]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[7]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[8]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[9]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[10]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[11]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[12]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[13]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[14]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_S[15]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[1]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[2]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[3]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[4]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[5]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[6]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[7]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[8]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[9]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[10]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[11]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[12]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[13]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[14]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[15]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[16]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[17]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[18]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[19]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[20]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[21]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[22]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[23]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[24]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_RC_T[25]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_err" IO_TYPE=LVCMOS33 ;
+BLOCK JTAGPATHS ;
+LOCATE COMP "o_RC_F[0]" SITE "U13" ;
+LOCATE COMP "o_RC_F[1]" SITE "U12" ;
+LOCATE COMP "o_RC_F[2]" SITE "T12" ;
+LOCATE COMP "o_RC_F[3]" SITE "T11" ;
+LOCATE COMP "o_RC_F[4]" SITE "U11" ;
+LOCATE COMP "o_RC_F[5]" SITE "V11" ;
+LOCATE COMP "o_RC_F[6]" SITE "W11" ;
+LOCATE COMP "o_RC_F[7]" SITE "U10" ;
+LOCATE COMP "o_RC_S[0]" SITE "T10" ;
+LOCATE COMP "o_RC_S[1]" SITE "W9" ;
+LOCATE COMP "o_RC_S[2]" SITE "AB2" ;
+LOCATE COMP "o_RC_S[3]" SITE "Y3" ;
+LOCATE COMP "o_RC_S[4]" SITE "AA3" ;
+LOCATE COMP "o_RC_S[5]" SITE "AB3" ;
+LOCATE COMP "o_RC_S[6]" SITE "Y4" ;
+LOCATE COMP "o_RC_S[7]" SITE "AA4" ;
+LOCATE COMP "o_RC_S[8]" SITE "Y5" ;
+LOCATE COMP "o_RC_S[9]" SITE "W6" ;
+LOCATE COMP "o_RC_S[10]" SITE "AB5" ;
+LOCATE COMP "o_RC_S[11]" SITE "AB6" ;
+LOCATE COMP "o_RC_S[12]" SITE "Y6" ;
+LOCATE COMP "o_RC_S[13]" SITE "Y7" ;
+LOCATE COMP "o_RC_S[14]" SITE "AB7" ;
+LOCATE COMP "o_RC_S[15]" SITE "AA7" ;
+LOCATE COMP "o_RC_T[0]" SITE "AA8" ;
+LOCATE COMP "o_RC_T[1]" SITE "Y10" ;
+LOCATE COMP "o_RC_T[2]" SITE "AB10" ;
+LOCATE COMP "o_RC_T[3]" SITE "AA10" ;
+LOCATE COMP "o_RC_T[4]" SITE "AA11" ;
+LOCATE COMP "o_RC_T[5]" SITE "AB11" ;
+LOCATE COMP "o_RC_T[6]" SITE "AA12" ;
+LOCATE COMP "o_RC_T[7]" SITE "AB13" ;
+LOCATE COMP "o_RC_T[8]" SITE "V8" ;
+LOCATE COMP "o_RC_T[9]" SITE "V12" ;
+LOCATE COMP "o_RC_T[10]" SITE "W12" ;
+LOCATE COMP "o_RC_T[11]" SITE "Y12" ;
+LOCATE COMP "o_RC_T[12]" SITE "V13" ;
+LOCATE COMP "o_RC_T[13]" SITE "V14" ;
+LOCATE COMP "o_RC_T[14]" SITE "V16" ;
+LOCATE COMP "o_RC_T[15]" SITE "AB17" ;
+LOCATE COMP "o_RC_T[16]" SITE "Y18" ;
+LOCATE COMP "o_RC_T[17]" SITE "AA19" ;
+LOCATE COMP "o_RC_T[18]" SITE "AB20" ;
+LOCATE COMP "o_RC_T[19]" SITE "W19" ;
+LOCATE COMP "o_RC_T[20]" SITE "W17" ;
+LOCATE COMP "o_RC_T[21]" SITE "Y17" ;
+LOCATE COMP "o_RC_T[22]" SITE "T15" ;
+LOCATE COMP "o_RC_T[23]" SITE "U15" ;
+LOCATE COMP "o_RC_T[24]" SITE "T13" ;
+LOCATE COMP "o_RC_T[25]" SITE "AA13" ;
+LOCATE COMP "o_err" SITE "AB16" ;
+IOBUF PORT "o_OC_1[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[16]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[16]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_2[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[16]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_3[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[0]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[1]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[2]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[3]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[4]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[5]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[6]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[7]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[9]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[10]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[11]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[12]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[13]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[14]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[15]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[16]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[17]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[18]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[19]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[20]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[21]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[22]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[23]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[24]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[25]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[26]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[27]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[28]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[29]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[30]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_4[31]" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_OC_1[8]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_2[8]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_3[8]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_OC_4[8]" IO_TYPE=LVCMOS33 ;
+LOCATE COMP "o_OC_1[8]" SITE "D14" ;
+LOCATE COMP "o_OC_1[9]" SITE "G13" ;
+LOCATE COMP "o_OC_1[10]" SITE "C13" ;
+LOCATE COMP "o_OC_1[11]" SITE "F13" ;
+LOCATE COMP "o_OC_1[12]" SITE "C17" ;
+LOCATE COMP "o_OC_1[13]" SITE "F17" ;
+LOCATE COMP "o_OC_1[14]" SITE "D17" ;
+LOCATE COMP "o_OC_1[15]" SITE "E17" ;
+LOCATE COMP "o_OC_1[24]" SITE "N5" ;
+LOCATE COMP "o_OC_1[25]" SITE "D15" ;
+LOCATE COMP "o_OC_1[26]" SITE "P3" ;
+LOCATE COMP "o_OC_1[27]" SITE "M4" ;
+LOCATE COMP "o_OC_1[28]" SITE "R6" ;
+LOCATE COMP "o_OC_1[29]" SITE "T5" ;
+LOCATE COMP "o_OC_1[30]" SITE "P6" ;
+LOCATE COMP "o_OC_1[31]" SITE "U4" ;
+LOCATE COMP "o_OC_2[8]" SITE "C1" ;
+LOCATE COMP "o_OC_2[9]" SITE "C2" ;
+LOCATE COMP "o_OC_2[10]" SITE "C3" ;
+LOCATE COMP "o_OC_2[11]" SITE "B1" ;
+LOCATE COMP "o_OC_2[12]" SITE "H5" ;
+LOCATE COMP "o_OC_2[13]" SITE "H6" ;
+LOCATE COMP "o_OC_2[14]" SITE "H2" ;
+LOCATE COMP "o_OC_2[15]" SITE "H3" ;
+LOCATE COMP "o_OC_2[24]" SITE "T7" ;
+LOCATE COMP "o_OC_2[25]" SITE "U5" ;
+LOCATE COMP "o_OC_2[26]" SITE "W5" ;
+LOCATE COMP "o_OC_2[27]" SITE "T6" ;
+LOCATE COMP "o_OC_2[28]" SITE "E8" ;
+LOCATE COMP "o_OC_2[29]" SITE "E9" ;
+LOCATE COMP "o_OC_2[30]" SITE "E10" ;
+LOCATE COMP "o_OC_2[31]" SITE "D11" ;
+LOCATE COMP "o_OC_3[8]" SITE "A11" ;
+LOCATE COMP "o_OC_3[9]" SITE "A12" ;
+LOCATE COMP "o_OC_3[10]" SITE "B12" ;
+LOCATE COMP "o_OC_3[11]" SITE "A13" ;
+LOCATE COMP "o_OC_3[12]" SITE "B19" ;
+LOCATE COMP "o_OC_3[13]" SITE "C18" ;
+LOCATE COMP "o_OC_3[14]" SITE "A17" ;
+LOCATE COMP "o_OC_3[15]" SITE "B16" ;
+LOCATE COMP "o_OC_3[24]" SITE "B13" ;
+LOCATE COMP "o_OC_3[25]" SITE "B14" ;
+LOCATE COMP "o_OC_3[26]" SITE "B15" ;
+LOCATE COMP "o_OC_3[27]" SITE "C15" ;
+LOCATE COMP "o_OC_3[28]" SITE "G21" ;
+LOCATE COMP "o_OC_3[29]" SITE "E22" ;
+LOCATE COMP "o_OC_3[30]" SITE "E20" ;
+LOCATE COMP "o_OC_3[31]" SITE "D21" ;
+LOCATE COMP "o_OC_4[8]" SITE "G1" ;
+LOCATE COMP "o_OC_4[9]" SITE "G2" ;
+LOCATE COMP "o_OC_4[10]" SITE "G3" ;
+LOCATE COMP "o_OC_4[11]" SITE "F1" ;
+LOCATE COMP "o_OC_4[12]" SITE "C4" ;
+LOCATE COMP "o_OC_4[13]" SITE "C5" ;
+LOCATE COMP "o_OC_4[14]" SITE "G11" ;
+LOCATE COMP "o_OC_4[15]" SITE "E11" ;
+LOCATE COMP "o_OC_4[24]" SITE "E1" ;
+LOCATE COMP "o_OC_4[25]" SITE "D1" ;
+LOCATE COMP "o_OC_4[26]" SITE "E2" ;
+LOCATE COMP "o_OC_4[27]" SITE "D3" ;
+LOCATE COMP "o_OC_4[28]" SITE "C11" ;
+LOCATE COMP "o_OC_4[29]" SITE "A2" ;
+LOCATE COMP "o_OC_4[30]" SITE "B3" ;
+LOCATE COMP "o_OC_4[31]" SITE "A3" ;
+USE PRIMARY NET "i_sys_clk_c" ;
diff --git a/2.FW/CPLD2/Reg_file.v b/2.FW/CPLD2/Reg_file.v
new file mode 100644
index 0000000..21a838e
--- /dev/null
+++ b/2.FW/CPLD2/Reg_file.v
@@ -0,0 +1,167 @@
+module Reg_file (
+ input i_sys_clk,
+ input i_rst_n,
+
+ // Bus Interface
+ input i_wr_req,
+ input i_wr,
+ input [6:0] i_addr,
+ input [23:0] i_wdata,
+
+ output [23:0] o_rdata,
+ output o_rvalid,
+ output o_busy,
+ output o_err,
+
+ // Controller Interface
+ input i_con_done, // 1=IDLE/DONE, 0=BUSY
+ output o_exec,
+
+ // Direct Register Outputs
+ output [23:0] o_freq1,
+ output [23:0] o_freq2,
+ output [23:0] o_freq3,
+ output [23:0] o_freq4
+);
+
+ // --- Parameters ---
+ localparam REG_COUNT = 16;
+ localparam [23:0]
+ IDENT = 24'h400000|| 12'b0001_0000_0000, //CPLD2==1,version=1.0.0
+ STATE_INIT = 24'h800000;
+
+ // State Machine Definition
+ localparam IDLE = 4'd0;
+ localparam BUSY = 4'd1;
+ localparam EXEC_ACK = 4'd2; // Wait for controller to go BUSY (Done=0)
+ localparam EXEC_WAIT = 4'd3; // Wait for controller to go DONE (Done=1)
+
+ // --- Internal Signals ---
+ reg [3:0] state;
+ reg [23:0] regtable [0:REG_COUNT - 1];
+ reg [23:0] rdata_reg;
+
+ reg busy_flag;
+ reg err_flag;
+ reg rvalid_flag;
+
+ integer i;
+
+ // Mapping Control Bits
+ wire exec_bit = regtable[1][0];
+
+ always @(posedge i_sys_clk or negedge i_rst_n) begin
+ if (!i_rst_n) begin
+ for (i = 0; i < REG_COUNT; i = i + 1) begin
+ regtable[i] <= 24'h0;
+ end
+ regtable[0] <= IDENT;
+ regtable[1] <= STATE_INIT;
+
+ rvalid_flag <= 1'b0;
+ busy_flag <= 1'b0;
+ err_flag <= 1'b0;
+ state <= IDLE;
+ end
+ else begin
+ case (state)
+ IDLE: begin
+ rvalid_flag <= 1'b0;
+ err_flag <= 1'b0;
+
+ // Priority Check: Did we crash/reset while EXEC bit was still 1?
+ if (exec_bit == 1'b1) begin
+ state <= EXEC_ACK;
+ busy_flag <= 1'b1;
+ end
+ else if (i_wr_req == 1'b1) begin
+ busy_flag <= 1'b1;
+ state <= BUSY;
+
+ // Addr Sanity Check
+ if ((i_wr && (i_addr == 'd0 || i_addr >= REG_COUNT)) ||
+ (!i_wr && (i_addr >= REG_COUNT)))
+ begin
+ err_flag <= 1'b1;
+ end
+ end
+ else begin
+ busy_flag <= 1'b0;
+ end
+ end
+
+ BUSY: begin
+ if (err_flag) begin
+ state <= IDLE;
+ end
+ else begin
+ if (i_wr == 1'b1) begin // --- WRITE ---
+ if (exec_bit == 1'b1) begin
+ // Cannot write if Controller is already running
+ err_flag <= 1'b1;
+ state <= IDLE;
+ end
+ else begin
+ regtable[i_addr] <= i_wdata;
+
+ // Check if this write is a "Start Command"
+ if (i_addr == 7'd1 && i_wdata[0] == 1'b1) begin
+ // Go to Handshake Start
+ state <= EXEC_ACK;
+ end else begin
+ state <= IDLE;
+ end
+ end
+ end
+ else begin // --- READ ---
+ rdata_reg <= regtable[i_addr];
+ rvalid_flag <= 1'b1;
+ state <= IDLE;
+ end
+ end
+ end
+
+ // --- EXEC PHASE 1: ACK ---
+ // Wait for Controller to register the command and pull 'done' LOW (Busy)
+ EXEC_ACK: begin
+ busy_flag <= 1'b1;
+ if (i_con_done == 1'b0) begin
+ state <= EXEC_WAIT;
+ end
+ // Optional: Timeout counter here to prevent hanging if Controller is dead
+ end
+
+ // --- EXEC PHASE 2: WAIT ---
+ // Now wait for Controller to finish and pull 'done' HIGH (Idle/Ready)
+ EXEC_WAIT: begin
+ busy_flag <= 1'b1;
+ if (i_con_done == 1'b1) begin
+ // 1. Clear the Exec bit (Auto-Clear)
+ // 2. Set the Ready bit (Bit 23) if you wish
+ regtable[1] <= {1'b1, regtable[1][22:1], 1'b0};
+
+ busy_flag <= 1'b0;
+ state <= IDLE;
+ end
+ end
+
+ default: state <= IDLE;
+ endcase
+ end
+ end
+
+ assign o_rvalid = rvalid_flag;
+ assign o_rdata = rdata_reg;
+ assign o_busy = busy_flag;
+ assign o_err = err_flag;
+
+ // Output the control bit to the controller
+ // This stays HIGH during both EXEC_ACK and EXEC_WAIT
+ assign o_exec = exec_bit;
+
+ assign o_freq1 = regtable[2];
+ assign o_freq2 = regtable[3];
+ assign o_freq3 = regtable[4];
+ assign o_freq4 = regtable[5];
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD2/RelayConTop.v b/2.FW/CPLD2/RelayConTop.v
new file mode 100644
index 0000000..a8f3b7c
--- /dev/null
+++ b/2.FW/CPLD2/RelayConTop.v
@@ -0,0 +1,118 @@
+module RelayConTop (
+ input i_sys_clk,
+ input i_rst_n,
+
+ input i_sclk,
+ input i_mosi,
+ input i_cs,
+ output o_miso,
+ output o_rvalid,
+ input i_rready,
+ input i_wvaild,
+ output o_wready,
+ output o_err,
+ output [7:0]o_RC_F, //Ref: Schematic
+ output [15:0]o_RC_S,
+ output [25:0]o_RC_T, //Actually ONLY 25 pin(rest is on CPLD1)
+ //output [3:0] o_OC_x09,
+ //output [3:0] o_OC_x25,
+ output [31:0]o_OC_1,
+ output [31:0]o_OC_2,
+ output [31:0]o_OC_3,
+ output [31:0]o_OC_4
+);
+
+ wire [7:0] RC_F;
+ wire [15:0] RC_S;
+ wire [31:0] RC_T;
+ wire [3:0]OC_x09 ;
+ wire [3:0]OC_x25 ;
+
+ wire [23:0]r_data ;
+ wire [23:0]w_data ;
+ wire [6:0]reg_addr ;
+
+ wire cmd_valid;
+ wire reg_busy;
+ wire wr_flag; //1=write,0=read
+ wire bus_err_flag;
+ wire reg_err_flag;
+
+ wire con_exec;
+ wire [23:0]freq1_relay ;
+ wire [23:0]freq2_relay ;
+ wire [23:0]freq3_relay ;
+ wire [23:0]freq4_relay ;
+ wire con_rvalid;
+
+ wire con_done;
+
+ BUS_Con BUS_Con_2(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+ .i_rvaild(con_rvaild),
+ .i_wvaild(i_wvaild),
+ .i_reg_busy(reg_busy),
+ .i_rdata(r_data),
+ .o_cmd_vaild(cmd_valid),
+ .o_wr(wr_flag),
+ .o_miso(o_miso),
+ .o_rvaild(o_rvalid),
+ .o_wready(o_wready),
+ .o_data(w_data),
+ .o_addr(reg_addr),
+ .o_err(bus_err_flag)
+ );
+
+ Reg_file CPLD_Reg_2(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_wr_req(cmd_valid),
+ .i_wr(wr_flag),
+ .i_addr(reg_addr),
+ .i_wdata(w_data),
+ .i_con_done(con_done), //Controller Exec Done
+ .o_freq1(freq1_relay), //Freq_Slot1
+ .o_freq2(freq2_relay), //Freq_Slot2
+ .o_freq3(freq3_relay), //Freq_Slot3
+ .o_freq4(freq4_relay), //Freq_Slot4
+ .o_rvalid(con_rvalid),
+ .o_rdata(r_data),
+ .o_exec(con_exec), //Exec cmd
+ .o_busy(reg_busy),
+ .o_err(reg_err_flag)
+ );
+
+ CPLD_Con CPLD_Con_2(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_con_exec(con_exec),
+ .i_freq_relay1(freq1_relay),
+ .i_freq_relay2(freq2_relay),
+ .i_freq_relay3(freq3_relay),
+ .i_freq_relay4(freq4_relay),
+ .o_con_done(con_done),
+ .o_RC_F(RC_F),
+ .o_RC_S(RC_S),
+ .o_RC_T(RC_T),
+ .o_OC_x09(OC_x09),
+ .o_OC_x25(OC_x25)
+ );
+
+
+ assign o_RC_F = RC_F;
+ assign o_RC_S = RC_S;
+ assign o_RC_T = RC_T[25:0];
+
+ //assign o_OC_1[8] = OC_x09[0];
+ //assign o_OC_2[8] = OC_x09[1];
+ //assign o_OC_3[8] = OC_x09[2];
+ //assign o_OC_4[8] = OC_x09[3];
+
+ assign o_err = bus_err_flag || reg_err_flag;
+
+
+endmodule
diff --git a/2.FW/CPLD2/tb_RelayConTop.sv b/2.FW/CPLD2/tb_RelayConTop.sv
new file mode 100644
index 0000000..e53f764
--- /dev/null
+++ b/2.FW/CPLD2/tb_RelayConTop.sv
@@ -0,0 +1,310 @@
+`timescale 1ns/1ps
+
+module tb_RelayConTop;
+
+ // 时钟和复位
+ reg i_sys_clk;
+ reg i_rst_n;
+
+ // SPI接口
+ reg i_sclk;
+ reg i_mosi;
+ reg i_cs;
+// wire o_miso;
+
+ // 流控制接口
+// wire o_rvaild;
+// reg i_rready;
+// reg i_wvaild;
+// wire o_wready;
+ wire o_err;
+
+ // 继电器控制输出
+ wire [7:0] o_RC_F;
+ wire [15:0] o_RC_S;
+ wire [31:0] o_RC_T;
+
+ // 测试变量
+ reg [31:0] spi_data;
+ integer test_pass;
+ integer test_fail;
+
+ // 实例化被测模块
+ RelayConTop DUT (
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+// .o_miso(o_miso),
+// .o_rvaild(o_rvaild),
+// .i_rready(i_rready),
+// .i_wvaild(i_wvaild),
+// .o_wready(o_wready),
+ .o_err(o_err),
+ .o_RC_F(o_RC_F),
+ .o_RC_S(o_RC_S),
+ .o_RC_T(o_RC_T)
+ );
+
+ // 时钟生成
+ initial begin
+ i_sys_clk = 0;
+ forever #5 i_sys_clk = ~i_sys_clk; // 20MHz系统时钟
+ end
+
+ // SPI时钟生成(比系统时钟慢)
+ initial begin
+ i_sclk = 0;
+ forever #50 i_sclk = ~i_sclk; // 2MHz SPI时钟
+ end
+
+ // 主测试流程
+ initial begin
+ // 初始化
+ initialize();
+
+ // 测试计数器
+ test_pass = 0;
+ test_fail = 0;
+
+ $display("=== CPLD2 Controller Test Start ===");
+
+ // 测试1: 复位后寄存器读取
+ test_reset_registers();
+
+
+ // 测试2: 寄存器写入和读取
+ test_register_write_read();
+
+ // 测试3: EXEC命令执行测试
+ test_exec_command();
+
+ // 测试4: 错误条件测试
+ test_error_conditions();
+
+ // 测试5: SPI连续传输测试
+ test_spi_continuous();
+
+ // 测试6: 边界条件测试
+ test_boundary_conditions();
+
+ // 总结
+ $display("=== Test Done ===");
+ $display("PASS: %0d", test_pass);
+ $display("Failed: %0d", test_fail);
+
+ if (test_fail == 0) begin
+ $display("*** ALL TEST PASSED! ***");
+ end else begin
+ $display("*** TEST FAILED FOUND!! CHECK DESIGN ***");
+ end
+
+ #1000 $finish;
+ end
+
+ // 初始化任务
+ task initialize;
+ begin
+ i_rst_n = 1;
+ i_cs = 1;
+ i_mosi = 0;
+ #100;
+ i_rst_n = 0;
+ #200;
+ i_rst_n = 1;
+ i_cs = 1;
+ $display("Initialize DONE!");
+ end
+ endtask
+
+ // SPI发送任务
+ task spi_send;
+ input [31:0] data;
+ integer i;
+ begin
+ #50;
+ i_cs = 0; // 片选有效
+
+ for (i = 31; i >= 0 ; i--) begin
+ #50; // 在SCLK上升沿前设置数据
+ i_mosi = data[i];
+ #50; // 等待SCLK上升沿
+ end
+ #50
+ i_cs = 1; // 片选无效
+ #200;
+ end
+ endtask
+
+ // 测试1: 复位后寄存器读取
+ task test_reset_registers;
+ begin
+ $display("--- TEST1: REG READ AFTER RST ---");
+ // 读取芯片ID寄存器 (地址0)
+ spi_data = {1'b1,23'h0, 1'b0,7'h0}; // 读操作,地址0,TEST
+ spi_send(spi_data);
+
+ // 检查返回值(应该在MISO上看到0x400000)
+ #1000;
+ check_result(1, "CPLD READ ID");
+ end
+ endtask
+
+ // 测试2: 寄存器写入和读取
+ task test_register_write_read;
+ begin
+ $display("--- TEST2: REG READ & WRITE ---");
+
+ // 写入频率槽1寄存器 (地址2)
+ spi_data = {24'h123456,1'b1,7'h2}; // 写操作,地址2,数据0x123456
+ spi_send(spi_data);
+ #500;
+
+ // 读取频率槽1寄存器验证
+ spi_data = {24'h0, 1'b0, 7'h2}; // 读操作,地址2
+ spi_send(spi_data);
+ #500;
+
+ check_result(1, "REG READ & WRITE");
+ end
+ endtask
+
+ // 测试3: EXEC命令执行测试
+ task test_exec_command;
+ begin
+ $display("--- TEST3: EXEC TEST ---");
+
+ // 设置EXEC位 (地址1的bit0)
+ spi_data = {24'h000001, 1'b1, 7'h1}; // 写操作,地址1,设置EXEC位
+ spi_send(spi_data);
+ #1000;
+
+ check_result(1, "EXEC TEST");
+ end
+ endtask
+
+ // 测试4: 错误条件测试
+ task test_error_conditions;
+ begin
+ $display("--- 测试4: ERR TEST ---");
+
+ // 测试4.1: 写入只读寄存器 (地址0)
+ spi_data = {24'hDEADBE,1'b1, 7'h0 }; // 尝试写入只读寄存器
+ spi_send(spi_data);
+ #500;
+
+ // 测试4.2: 访问超出范围的地址
+ spi_data = {24'h0, 1'b0, 7'h20}; // 读取地址32(超出范围)
+ spi_send(spi_data);
+ #500;
+
+ check_result(1, "ERR TEST");
+ end
+ endtask
+
+ // 测试5: SPI连续传输测试
+ task test_spi_continuous;
+ begin
+ $display("--- 测试5: SPI BATCH READ&WRITE ---");
+
+ // 连续写入多个寄存器
+ spi_data = {24'h111111, 7'h2, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h222222, 7'h3, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h333333, 7'h4, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ // 连续读取验证
+ spi_data = {24'h0, 7'h2, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h0, 7'h3, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h0, 7'h4, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ check_result(1, "SPI BATCH READ&WRITE");
+ end
+ endtask
+
+ // 测试6: 边界条件测试
+ task test_boundary_conditions;
+ begin
+ $display("--- TEST6: EDGE CASE TEST ---");
+
+ // 测试6.1: 复位期间的SPI访问
+ i_rst_n = 0;
+ spi_data = {24'h0, 7'h1, 1'b0};
+ spi_send(spi_data);
+ #200;
+ i_rst_n = 1;
+ #500;
+
+ // 测试6.2: CS信号异常
+ i_cs = 0;
+ #50;
+ i_cs = 1; // 短暂CS脉冲
+ #50;
+ i_cs = 0;
+ #1000;
+ i_cs = 1;
+ #500;
+
+ check_result(1, "EDGE CASE TEST");
+ end
+ endtask
+
+ // 结果检查任务
+ task check_result;
+ input expected;
+ input [120:1] test_name; // 字符数组存储测试名称
+ begin
+ if (expected) begin
+ test_pass = test_pass + 1;
+ $display("TEST %s - PASSED", test_name);
+ end else begin
+ test_fail = test_fail + 1;
+ $display("TEST %s - FAILED", test_name);
+ end
+ end
+ endtask
+
+ /*
+ // 监控关键信号
+ initial begin
+ $display("TIME | CS | SCLK | MOSI | MISO | ERR | RC_CON");
+ $display("-----|----|------|------|------|------|--------");
+ forever begin
+ #1000;
+ $display("%4t | %b | %b | %b | %b | %b | F:%h S:%h T:%h",
+ $time, i_cs, i_sclk, i_mosi, o_miso, o_err,
+ o_RC_F, o_RC_S, o_RC_T);
+ end
+ end
+ */
+
+ // VCD文件生成(用于波形查看)
+ initial begin
+ $dumpfile("relay_con_top.vcd");
+ $dumpvars(0, tb_RelayConTop);
+ end
+
+ // 超时保护
+ initial begin
+ #5000000; // 5ms超时
+ $display("!!! TEST TIMEOUT !!!");
+ $finish;
+ end
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD2/tb_RelayConTop/source_files.lst b/2.FW/CPLD2/tb_RelayConTop/source_files.lst
new file mode 100644
index 0000000..7abd691
--- /dev/null
+++ b/2.FW/CPLD2/tb_RelayConTop/source_files.lst
@@ -0,0 +1,5 @@
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD2/CPLD_Freq_Con.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD2/Reg_file.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD2/BUS_Con.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD2/RelayConTop.v=work,"
+"D:/WORK/ManLin/Verify/FPGA/Lattice/NewExtIns/CPLD2/tb_RelayConTop.sv=work,"
diff --git a/2.FW/CPLD3/.gitignore b/2.FW/CPLD3/.gitignore
new file mode 100644
index 0000000..bd935a3
--- /dev/null
+++ b/2.FW/CPLD3/.gitignore
@@ -0,0 +1,3 @@
+# Lattice Diamond 实现输出目录
+# 根目录 .gitignore 已覆盖大部分 pattern,此处仅确保 impl1/ 被忽略
+impl1/
diff --git a/2.FW/CPLD3/.run_manager.ini b/2.FW/CPLD3/.run_manager.ini
new file mode 100644
index 0000000..cfb561e
--- /dev/null
+++ b/2.FW/CPLD3/.run_manager.ini
@@ -0,0 +1,9 @@
+[Runmanager]
+Geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\0\0\0\0\x3\x30\0\0\x1!\0\0\x4\x11\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0)
+windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x1\0\0\0\0\0\0\0\x1\xff\xff\xff\xff\x3\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
+headerState=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x16\0\xe0?\0\0\0\t\0\0\0\x10\0\0\0\x64\0\0\0\xf\0\0\0\x64\0\0\0\xe\0\0\0\x64\0\0\0\r\0\0\0\x64\0\0\0\x15\0\0\0\x64\0\0\0\x14\0\0\0\x64\0\0\0\x13\0\0\0\x64\0\0\0\x12\0\0\0\x64\0\0\0\x11\0\0\0\x64\0\0\x4\xd3\0\0\0\x16\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x3\0\0\0#\0\0\0\x1\0\0\0\x2\0\0\x4\xb0\0\0\0\f\0\0\0\0\0\0\0\0\0\0\0\t\0\0\0\0)
+
+[impl1%3CStrategy1%3E]
+isChecked=false
+isHidden=false
+isExpanded=false
diff --git a/2.FW/CPLD3/.setting.ini b/2.FW/CPLD3/.setting.ini
new file mode 100644
index 0000000..5caf3da
--- /dev/null
+++ b/2.FW/CPLD3/.setting.ini
@@ -0,0 +1,2 @@
+[General]
+Export.auto_tasks=Bitgen, Jedecgen
diff --git a/2.FW/CPLD3/.spread_sheet.ini b/2.FW/CPLD3/.spread_sheet.ini
new file mode 100644
index 0000000..6c511f4
--- /dev/null
+++ b/2.FW/CPLD3/.spread_sheet.ini
@@ -0,0 +1,3 @@
+[General]
+COLUMN_POS_INFO_NAME_-1_0=Prioritize
+COLUMN_POS_INFO_NAME_-1_1=PIO Register
diff --git a/2.FW/CPLD3/.spreadsheet_view.ini b/2.FW/CPLD3/.spreadsheet_view.ini
new file mode 100644
index 0000000..ca48b22
--- /dev/null
+++ b/2.FW/CPLD3/.spreadsheet_view.ini
@@ -0,0 +1,76 @@
+[General]
+pin_sort_type=0
+pin_sort_ascending=true
+sig_sort_type=0
+sig_sort_ascending=true
+active_Sheet=Pin Assignments
+
+[Port%20Assignments]
+Name="193,0"
+Group%20By="88,1"
+Pin="79,2"
+BANK="60,3"
+BANK_VCC="88,4"
+VREF="60,5"
+IO_TYPE="147,6"
+PULLMODE="97,7"
+DRIVE="67,8"
+SLEWRATE="91,9"
+CLAMP="67,10"
+OPENDRAIN="95,11"
+DIFFRESISTOR="116,12"
+DIFFDRIVE="95,13"
+HYSTERESIS="102,14"
+Outload%20%28pF%29="116,15"
+MaxSkew="81,16"
+Clock%20Load%20Only="137,17"
+SwitchingID="109,18"
+Ground%20plane%20PCB%20noise%20%28mV%29="221,19"
+Power%20plane%20PCB%20noise%20%28mV%29="214,20"
+SSO%20Allowance%28%25%29="144,21"
+sort_columns="Name,Ascending"
+
+[Pin%20Assignments]
+Pin="93,0"
+Pad%20Name="88,1"
+Dual%20Function="158,2"
+Polarity="88,3"
+BANK="0,4"
+BANK_VCC="88,5"
+IO_TYPE="147,6"
+Signal%20Name="177,7"
+Signal%20Type="115,8"
+sort_columns="Pin,Ascending"
+
+[Clock%20Resource]
+Clock%20Type="100,ELLIPSIS"
+Clock%20Name="100,ELLIPSIS"
+Selection="100,ELLIPSIS"
+
+[Global%20Preferences]
+Preference%20Name="231,ELLIPSIS"
+Preference%20Value="236,ELLIPSIS"
+
+[Cell%20Mapping]
+Type="100,ELLIPSIS"
+Name="223,ELLIPSIS"
+Din\Dout="83,ELLIPSIS"
+PIO%20Register="100,ELLIPSIS"
+
+[Route%20Priority]
+Type="100,ELLIPSIS"
+Name="100,ELLIPSIS"
+Prioritize="100,ELLIPSIS"
+
+[Timing%20Preferences]
+Preference%20Name="129,ELLIPSIS"
+Preference%20Value="111,ELLIPSIS"
+Preference%20Unit="103,ELLIPSIS"
+
+[Group]
+Group%20Type\Name="134,ELLIPSIS"
+Value="42,ELLIPSIS"
+
+[Misc%20Preferences]
+Preference%20Name="117,ELLIPSIS"
+Preference%20Value="111,ELLIPSIS"
diff --git a/2.FW/CPLD3/BUS_Con.v b/2.FW/CPLD3/BUS_Con.v
new file mode 100644
index 0000000..cc61c73
--- /dev/null
+++ b/2.FW/CPLD3/BUS_Con.v
@@ -0,0 +1,215 @@
+module BUS_Con (
+ input i_sys_clk,
+ input i_rst_n,
+
+ // SPI Interface
+ input i_sclk,
+ input i_mosi,
+ input i_cs,
+ output o_miso, // <-- MISO Logic added here
+
+ // Local Interface
+ output o_rvalid, // (Typo in original: o_rvalid)
+ input i_rvalid, // Valid signal from Backend (Data is ready)
+ input i_wvalid,
+ output o_wready,
+ input i_reg_busy,
+ input [23:0] i_rdata, // Data from Backend to send to Master
+ output o_wr,
+ output o_cmd_valid,
+ output [23:0] o_data,
+ output [6:0] o_addr,
+ output o_err
+);
+
+ // --- 1. Synchronization ---
+ reg [1:0] cs_sync;
+ reg [1:0] sclk_sync;
+ reg [1:0] mosi_sync;
+
+ wire cs_active;
+ wire cs_rise;
+ wire sclk_rise; // For Sampling MOSI
+ wire sclk_fall; // For Shifting MISO
+ wire mosi_data;
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ cs_sync <= 2'b11;
+ sclk_sync <= 2'b00;
+ mosi_sync <= 2'b00;
+ end else begin
+ cs_sync <= {cs_sync[0], i_cs};
+ sclk_sync <= {sclk_sync[0], i_sclk};
+ mosi_sync <= {mosi_sync[0], i_mosi};
+ end
+ end
+
+ assign cs_active = ~cs_sync[1];
+ assign cs_rise = (!cs_sync[1] && cs_sync[0]);
+
+ // SPI Mode 0: Sample MOSI on Rising, Shift MISO on Falling
+ assign sclk_rise = (!sclk_sync[1] && sclk_sync[0]);
+ assign sclk_fall = (sclk_sync[1] && !sclk_sync[0]); // Logic for MISO
+ assign mosi_data = mosi_sync[1];
+
+ // --- 2. MOSI (Receive) Logic ---
+ reg [31:0] recv_reg;
+ reg [5:0] bit_cnt;
+ reg data_ready;
+ reg err_flag;
+ reg [1:0] state;
+ //
+ reg [31:0] tx_buffer; // Holds data waiting for the next CS Low
+ reg [31:0] miso_shift; // The actual shifter
+ // Output Registers
+ reg [6:0] addr_out;
+ reg [23:0] data_out;
+ reg wr_out;
+ reg cmd_valid_out;
+
+ //
+ localparam IDLE = 2'b00;
+ localparam CMD_SENT = 2'b01;
+ localparam WAIT_BUSY = 2'b10;
+ localparam DONE = 2'b11;
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ recv_reg <= 32'd0;
+ bit_cnt <= 6'd0;
+ data_ready <= 1'b0;
+ err_flag <= 1'b0;
+ end
+ else begin
+ data_ready <= 1'b0;
+
+ if (cs_active) begin
+ if (sclk_rise) begin
+ recv_reg <= {recv_reg[30:0], mosi_data};
+ bit_cnt <= bit_cnt + 1'b1;
+ end
+ else if (cs_rise) begin
+ if (bit_cnt == 6'd32) begin
+ data_ready <= 1'b1;
+ err_flag <= 1'b0;
+ bit_cnt <= 6'd0;
+ end
+ else if (bit_cnt != 0) begin
+ err_flag <= 1'b1;
+ bit_cnt <= 6'd0;
+ recv_reg <= 'd0;
+ end
+ end
+ end
+ if (state == DONE) begin
+ recv_reg <= 'd0;
+ end
+ end
+ end
+
+ // --- 3. MISO (Transmit) Logic ---
+ // Protocol: We shift out 32 bits.
+ // Format: [8 bit Status/Padding] + [24 bit i_rdata]
+
+
+ // Capture data from backend when valid
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ tx_buffer <= 32'd0;
+ end else begin
+ // If backend provides valid read data, store it.
+ // We pad the top 8 bits with Zeros (or you can put status flags here)
+ if (i_rvalid) begin
+ tx_buffer <= {8'h00, i_rdata};
+ end
+ end
+ end
+
+ // Shift data out
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ miso_shift <= 32'd0;
+ end else begin
+ if (!cs_active) begin
+ // Pre-load the shifter while CS is High
+ // This ensures Bit 31 is ready BEFORE the first clock edge
+ miso_shift <= tx_buffer;
+ end else begin
+ // Shift on Falling Edge (Master samples on Rising)
+ if (sclk_fall) begin
+ miso_shift <= {miso_shift[30:0], 1'b0};
+ end
+ end
+ end
+ end
+
+ // Tri-state MISO when CS is high (optional, usually good practice)
+ // If your board doesn't need tristate, just use: assign o_miso = miso_shift[31];
+ assign o_miso = (cs_active) ? miso_shift[31] : 1'bz;
+
+ // --- 4. Register Control FSM ---
+
+
+
+ always @(posedge i_sys_clk) begin
+ if (!i_rst_n) begin
+ state <= IDLE;
+ cmd_valid_out <= 1'b0;
+ addr_out <= 7'd0;
+ data_out <= 24'd0;
+ wr_out <= 1'b0;
+ end else begin
+ case (state)
+ IDLE: begin
+ if (data_ready) begin
+ addr_out <= recv_reg[30:24];
+ data_out <= recv_reg[23:0];
+ wr_out <= recv_reg[31];
+
+ if (!i_reg_busy) begin
+ cmd_valid_out <= 1'b1;
+ state <= CMD_SENT;
+ end else begin
+ state <= WAIT_BUSY;
+ end
+ end
+ end
+
+ WAIT_BUSY: begin
+ if (!i_reg_busy) begin
+ cmd_valid_out <= 1'b1;
+ state <= CMD_SENT;
+ end
+ end
+
+ CMD_SENT: begin
+ cmd_valid_out <= 1'b0;
+ state <= DONE;
+ end
+
+ DONE: begin
+ if (!i_reg_busy) begin
+ state <= IDLE;
+ addr_out <= 'd0;
+ data_out <= 'd0;
+ wr_out <= 'd0;
+ end
+ end
+ endcase
+ end
+ end
+
+ assign o_addr = addr_out;
+ assign o_data = data_out;
+ assign o_wr = wr_out;
+ assign o_cmd_valid = cmd_valid_out;
+ assign o_err = err_flag;
+ assign o_wready = (state == IDLE);
+
+ // Pass through unused signal or hook it up if needed
+ assign o_rvalid = 1'b0;
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD3/CPLD_Con.v b/2.FW/CPLD3/CPLD_Con.v
new file mode 100644
index 0000000..21b6689
--- /dev/null
+++ b/2.FW/CPLD3/CPLD_Con.v
@@ -0,0 +1,91 @@
+module CPLD_Con (
+ input i_sys_clk,
+ input i_rst_n,
+ input i_con_exec,
+ input [23:0]i_freq_relay1,
+ input [23:0]i_freq_relay2,
+ input [23:0]i_freq_relay3,
+ input [23:0]i_freq_relay4,
+ output o_con_done,
+ output [3:0]o_PMU_RC,
+ output o_err
+);
+
+ //Relay Reg
+ reg [3:0] PMU_RC;
+
+ //Flags
+ reg exec_flag;
+ reg err_flag;
+ reg [3:0]slot_exec_flag;
+ reg done_flag;
+
+ //Counter
+ reg [15:0]delay_cnt;
+
+ always @(posedge i_sys_clk) begin
+ if (i_rst_n == 1'b0) begin
+ delay_cnt <= 'd0;
+ end
+ else begin
+ if (exec_flag == 1'b1) begin
+ delay_cnt <= delay_cnt + 1'd1;
+ end
+ else begin
+ delay_cnt <= 'd0;
+ end
+ end
+ end
+
+ always @(posedge i_sys_clk) begin
+ if (i_rst_n == 1'b0) begin
+ exec_flag <= 1'b0;
+ err_flag <= 1'b0;
+ slot_exec_flag <= 'd0;
+ done_flag <= 'd1;
+ PMU_RC <= 4'b1111;
+ end
+ else begin
+ if ((i_con_exec == 1'b1) & (exec_flag == 1'b0)) begin
+ exec_flag <= 1'b1;
+ done_flag <= 1'b0;
+ //To DO: More Sanity Check?
+ if ( (i_freq_relay1[0] + i_freq_relay2[0] + i_freq_relay3[0] + i_freq_relay4[0]) > 2'd1 ) begin
+ err_flag <= 1'b1;
+ end
+ else begin
+ slot_exec_flag[0] <= i_freq_relay1[0];
+ slot_exec_flag[1] <= i_freq_relay2[0];
+ slot_exec_flag[2] <= i_freq_relay3[0];
+ slot_exec_flag[3] <= i_freq_relay4[0];
+ end
+ end
+ else if (exec_flag == 1'b1) begin
+ case (slot_exec_flag)
+ 4'b0001: begin
+ PMU_RC <= 4'b1111;
+ end
+ 4'b0010: begin
+ PMU_RC <= 4'b1100;
+ end
+ 4'b0100: begin
+ PMU_RC <= 4'b1010;
+ end
+ 4'b1000: begin
+ PMU_RC <= 4'b0110;
+ end
+ endcase
+ done_flag <= 1'b1;
+ end
+ end
+ if (done_flag == 1) begin
+ exec_flag <= 1'b0;
+ end
+ end
+
+ assign o_con_done = done_flag;
+ assign o_PMU_RC = PMU_RC;
+ assign o_err = err_flag;
+
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD3/NewExtIns_CPLD3.ccl b/2.FW/CPLD3/NewExtIns_CPLD3.ccl
new file mode 100644
index 0000000..dcf391b
--- /dev/null
+++ b/2.FW/CPLD3/NewExtIns_CPLD3.ccl
@@ -0,0 +1 @@
+VERSION=20110520
diff --git a/2.FW/CPLD3/NewExtIns_CPLD3.ldf b/2.FW/CPLD3/NewExtIns_CPLD3.ldf
new file mode 100644
index 0000000..7da2797
--- /dev/null
+++ b/2.FW/CPLD3/NewExtIns_CPLD3.ldf
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2.FW/CPLD3/NewExtIns_CPLD3.lpf b/2.FW/CPLD3/NewExtIns_CPLD3.lpf
new file mode 100644
index 0000000..ef512d7
--- /dev/null
+++ b/2.FW/CPLD3/NewExtIns_CPLD3.lpf
@@ -0,0 +1,29 @@
+rvl_alias "i_sys_clk" "i_sys_clk";
+RVL_ALIAS "i_sys_clk" "i_sys_clk";
+BLOCK RESETPATHS ;
+BLOCK ASYNCPATHS ;
+LOCATE COMP "i_sys_clk" SITE "B9" ;
+LOCATE COMP "i_rst_n" SITE "Y14" ;
+LOCATE COMP "i_sclk" SITE "AA10" ;
+LOCATE COMP "i_cs" SITE "AB11" ;
+LOCATE COMP "i_mosi" SITE "AB12" ;
+LOCATE COMP "o_miso" SITE "AA14" ;
+IOBUF PORT "i_cs" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_mosi" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_rst_n" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "i_sclk" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_miso" IO_TYPE=LVCMOS33 PULLMODE=NONE DRIVE=8 ;
+IOBUF PORT "o_rvaild" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "o_wready" IO_TYPE=LVCMOS33 PULLMODE=NONE ;
+IOBUF PORT "i_sys_clk" DRIVE=NA IO_TYPE=LVCMOS33 SLEWRATE=NA PULLMODE=DOWN ;
+IOBUF PORT "o_err" IO_TYPE=LVCMOS33 ;
+LOCATE COMP "o_err" SITE "AB16" ;
+LOCATE COMP "o_PMU_RC[0]" SITE "V2" ;
+LOCATE COMP "o_PMU_RC[1]" SITE "N18" ;
+LOCATE COMP "o_PMU_RC[2]" SITE "P19" ;
+LOCATE COMP "o_PMU_RC[3]" SITE "P18" ;
+IOBUF PORT "o_PMU_RC[0]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_PMU_RC[1]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_PMU_RC[2]" IO_TYPE=LVCMOS33 ;
+IOBUF PORT "o_PMU_RC[3]" IO_TYPE=LVCMOS33 ;
+BLOCK JTAGPATHS ;
diff --git a/2.FW/CPLD3/Reg_file.v b/2.FW/CPLD3/Reg_file.v
new file mode 100644
index 0000000..d1121a5
--- /dev/null
+++ b/2.FW/CPLD3/Reg_file.v
@@ -0,0 +1,165 @@
+module Reg_file (
+ input i_sys_clk,
+ input i_rst_n,
+
+ // Bus Interface
+ input i_wr_req,
+ input i_wr,
+ input [6:0] i_addr,
+ input [23:0] i_wdata,
+
+ output [23:0] o_rdata,
+ output o_rvalid,
+ output o_busy,
+ output o_err,
+
+ // Controller Interface
+ input i_con_done, // 1=IDLE/DONE, 0=BUSY
+ output o_exec,
+
+ // Direct Register Outputs
+ output [23:0] o_freq1,
+ output [23:0] o_freq2,
+ output [23:0] o_freq3,
+ output [23:0] o_freq4
+);
+
+ // --- Parameters ---
+ localparam REG_COUNT = 16;
+ localparam [23:0]
+ IDENT = 24'h800000|| 12'b0001_0000_0000, //CPLD3==1,version=1.0.0
+ STATE_INIT = 24'h800000;
+
+ // State Machine Definition
+ localparam IDLE = 4'd0;
+ localparam BUSY = 4'd1;
+ localparam EXEC_ACK = 4'd2; // Wait for controller to go BUSY (Done=0)
+ localparam EXEC_WAIT = 4'd3; // Wait for controller to go DONE (Done=1)
+
+ // --- Internal Signals ---
+ reg [3:0] state;
+ reg [23:0] regtable [0:REG_COUNT - 1];
+ reg [23:0] rdata_reg;
+
+ reg busy_flag;
+ reg err_flag;
+ reg rvalid_flag;
+
+ integer i;
+
+ // Mapping Control Bits
+ wire exec_bit = regtable[1][0];
+
+ always @(posedge i_sys_clk or negedge i_rst_n) begin
+ if (!i_rst_n) begin
+ for (i = 0; i < REG_COUNT; i = i + 1) begin
+ regtable[i] <= 24'h0;
+ end
+ regtable[0] <= IDENT;
+ regtable[1] <= STATE_INIT;
+
+ rvalid_flag <= 1'b0;
+ busy_flag <= 1'b0;
+ err_flag <= 1'b0;
+ state <= IDLE;
+ end
+ else begin
+ case (state)
+ IDLE: begin
+ rvalid_flag <= 1'b0;
+ err_flag <= 1'b0;
+
+ // Priority Check: Did we crash/reset while EXEC bit was still 1?
+ if (exec_bit == 1'b1) begin
+ state <= EXEC_ACK;
+ busy_flag <= 1'b1;
+ end
+ else if (i_wr_req == 1'b1) begin
+ busy_flag <= 1'b1;
+ state <= BUSY;
+
+ // Addr Sanity Check
+ if ((i_wr && (i_addr == 'd0 || i_addr >= REG_COUNT)) ||
+ (!i_wr && (i_addr >= REG_COUNT)))
+ begin
+ err_flag <= 1'b1;
+ end
+ end
+ else begin
+ busy_flag <= 1'b0;
+ end
+ end
+
+ BUSY: begin
+ if (err_flag) begin
+ state <= IDLE;
+ end
+ else begin
+ if (i_wr == 1'b1) begin // --- WRITE ---
+ if (exec_bit == 1'b1) begin
+ // Cannot write if Controller is already running
+ err_flag <= 1'b1;
+ state <= IDLE;
+ end
+ else begin
+ regtable[i_addr] <= i_wdata;
+
+ // Check if this write is a "Start Command"
+ if (i_addr == 7'd1 && i_wdata[0] == 1'b1) begin
+ // Go to Handshake Start
+ state <= EXEC_ACK;
+ end else begin
+ state <= IDLE;
+ end
+ end
+ end
+ else begin // --- READ ---
+ rdata_reg <= regtable[i_addr];
+ rvalid_flag <= 1'b1;
+ state <= IDLE;
+ end
+ end
+ end
+
+ // --- EXEC PHASE 1: ACK ---
+ // Wait for Controller to register the command and pull 'done' LOW (Busy)
+ EXEC_ACK: begin
+ busy_flag <= 1'b1;
+ state <= EXEC_WAIT;
+ // Optional: Timeout counter here to prevent hanging if Controller is dead
+ end
+
+ // --- EXEC PHASE 2: WAIT ---
+ // Now wait for Controller to finish and pull 'done' HIGH (Idle/Ready)
+ EXEC_WAIT: begin
+ busy_flag <= 1'b1;
+ if (i_con_done == 1'b1) begin
+ // 1. Clear the Exec bit (Auto-Clear)
+ // 2. Set the Ready bit (Bit 23) if you wish
+ regtable[1] <= {1'b1, regtable[1][22:1], 1'b0};
+
+ busy_flag <= 1'b0;
+ state <= IDLE;
+ end
+ end
+
+ default: state <= IDLE;
+ endcase
+ end
+ end
+
+ assign o_rvalid = rvalid_flag;
+ assign o_rdata = rdata_reg;
+ assign o_busy = busy_flag;
+ assign o_err = err_flag;
+
+ // Output the control bit to the controller
+ // This stays HIGH during both EXEC_ACK and EXEC_WAIT
+ assign o_exec = exec_bit;
+
+ assign o_freq1 = regtable[2];
+ assign o_freq2 = regtable[3];
+ assign o_freq3 = regtable[4];
+ assign o_freq4 = regtable[5];
+
+endmodule
\ No newline at end of file
diff --git a/2.FW/CPLD3/RelayConTop.v b/2.FW/CPLD3/RelayConTop.v
new file mode 100644
index 0000000..37b488b
--- /dev/null
+++ b/2.FW/CPLD3/RelayConTop.v
@@ -0,0 +1,98 @@
+module RelayConTop (
+ input i_sys_clk,
+ input i_rst_n,
+
+ input i_sclk,
+ input i_mosi,
+ input i_cs,
+ output o_miso,
+ output o_rvaild,
+ input i_rready,
+ input i_wvaild,
+ output o_wready,
+ output o_err,
+ output o_con_done,
+ output [3:0]o_PMU_RC
+);
+
+ wire [3:0]PMU_RC ;
+
+
+ wire [23:0]r_data ;
+ wire [23:0]w_data ;
+ wire [6:0]reg_addr ;
+
+ wire cmd_vaild;
+ wire reg_busy;
+ wire wr_flag; //1=write,0=read
+ wire bus_err_flag;
+ wire reg_err_flag;
+ wire cpld_err_flag;
+
+ wire con_exec;
+ wire [23:0]freq1_relay ;
+ wire [23:0]freq2_relay ;
+ wire [23:0]freq3_relay ;
+ wire [23:0]freq4_relay ;
+ wire con_rvaild;
+
+ wire con_done;
+
+ BUS_Con Bus_Con_3(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+ .i_rvalid(con_rvalid),
+ .i_wvalid(i_wvalid),
+ .i_reg_busy(reg_busy),
+ .i_rdata(r_data),
+ .o_cmd_valid(cmd_vaild),
+ .o_wr(wr_flag),
+ .o_miso(o_miso),
+ .o_rvalid(o_rvalid),
+ .o_wready(o_wready),
+ .o_data(w_data),
+ .o_addr(reg_addr),
+ .o_err(bus_err_flag)
+ );
+
+ Reg_file CPLD_Reg_3(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_wr_req(cmd_vaild),
+ .i_wr(wr_flag),
+ .i_addr(reg_addr),
+ .i_wdata(w_data),
+ .i_con_done(con_done), //Controller Exec Done
+ .o_freq1(freq1_relay), //Freq_Slot1
+ .o_freq2(freq2_relay), //Freq_Slot2
+ .o_freq3(freq3_relay), //Freq_Slot3
+ .o_freq4(freq4_relay), //Freq_Slot4
+ .o_rvalid(con_rvalid),
+ .o_rdata(r_data),
+ .o_exec(con_exec), //Exec cmd
+ .o_busy(reg_busy),
+ .o_err(reg_err_flag)
+ );
+
+ CPLD_Con CPLD_Con_3(
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_con_exec(con_exec),
+ .i_freq_relay1(freq1_relay),
+ .i_freq_relay2(freq2_relay),
+ .i_freq_relay3(freq3_relay),
+ .i_freq_relay4(freq4_relay),
+ .o_con_done(con_done),
+ .o_PMU_RC(PMU_RC),
+ .o_err(cpld_err_flag)
+ );
+
+ assign o_con_done = con_done;
+ assign o_PMU_RC = PMU_RC;
+
+ assign o_err = bus_err_flag || reg_err_flag ||cpld_err_flag;
+
+endmodule
diff --git a/2.FW/CPLD3/piodrc.cfg b/2.FW/CPLD3/piodrc.cfg
new file mode 100644
index 0000000..e69de29
diff --git a/2.FW/CPLD3/tb_RelayConTop.sv b/2.FW/CPLD3/tb_RelayConTop.sv
new file mode 100644
index 0000000..e53f764
--- /dev/null
+++ b/2.FW/CPLD3/tb_RelayConTop.sv
@@ -0,0 +1,310 @@
+`timescale 1ns/1ps
+
+module tb_RelayConTop;
+
+ // 时钟和复位
+ reg i_sys_clk;
+ reg i_rst_n;
+
+ // SPI接口
+ reg i_sclk;
+ reg i_mosi;
+ reg i_cs;
+// wire o_miso;
+
+ // 流控制接口
+// wire o_rvaild;
+// reg i_rready;
+// reg i_wvaild;
+// wire o_wready;
+ wire o_err;
+
+ // 继电器控制输出
+ wire [7:0] o_RC_F;
+ wire [15:0] o_RC_S;
+ wire [31:0] o_RC_T;
+
+ // 测试变量
+ reg [31:0] spi_data;
+ integer test_pass;
+ integer test_fail;
+
+ // 实例化被测模块
+ RelayConTop DUT (
+ .i_sys_clk(i_sys_clk),
+ .i_rst_n(i_rst_n),
+ .i_sclk(i_sclk),
+ .i_mosi(i_mosi),
+ .i_cs(i_cs),
+// .o_miso(o_miso),
+// .o_rvaild(o_rvaild),
+// .i_rready(i_rready),
+// .i_wvaild(i_wvaild),
+// .o_wready(o_wready),
+ .o_err(o_err),
+ .o_RC_F(o_RC_F),
+ .o_RC_S(o_RC_S),
+ .o_RC_T(o_RC_T)
+ );
+
+ // 时钟生成
+ initial begin
+ i_sys_clk = 0;
+ forever #5 i_sys_clk = ~i_sys_clk; // 20MHz系统时钟
+ end
+
+ // SPI时钟生成(比系统时钟慢)
+ initial begin
+ i_sclk = 0;
+ forever #50 i_sclk = ~i_sclk; // 2MHz SPI时钟
+ end
+
+ // 主测试流程
+ initial begin
+ // 初始化
+ initialize();
+
+ // 测试计数器
+ test_pass = 0;
+ test_fail = 0;
+
+ $display("=== CPLD2 Controller Test Start ===");
+
+ // 测试1: 复位后寄存器读取
+ test_reset_registers();
+
+
+ // 测试2: 寄存器写入和读取
+ test_register_write_read();
+
+ // 测试3: EXEC命令执行测试
+ test_exec_command();
+
+ // 测试4: 错误条件测试
+ test_error_conditions();
+
+ // 测试5: SPI连续传输测试
+ test_spi_continuous();
+
+ // 测试6: 边界条件测试
+ test_boundary_conditions();
+
+ // 总结
+ $display("=== Test Done ===");
+ $display("PASS: %0d", test_pass);
+ $display("Failed: %0d", test_fail);
+
+ if (test_fail == 0) begin
+ $display("*** ALL TEST PASSED! ***");
+ end else begin
+ $display("*** TEST FAILED FOUND!! CHECK DESIGN ***");
+ end
+
+ #1000 $finish;
+ end
+
+ // 初始化任务
+ task initialize;
+ begin
+ i_rst_n = 1;
+ i_cs = 1;
+ i_mosi = 0;
+ #100;
+ i_rst_n = 0;
+ #200;
+ i_rst_n = 1;
+ i_cs = 1;
+ $display("Initialize DONE!");
+ end
+ endtask
+
+ // SPI发送任务
+ task spi_send;
+ input [31:0] data;
+ integer i;
+ begin
+ #50;
+ i_cs = 0; // 片选有效
+
+ for (i = 31; i >= 0 ; i--) begin
+ #50; // 在SCLK上升沿前设置数据
+ i_mosi = data[i];
+ #50; // 等待SCLK上升沿
+ end
+ #50
+ i_cs = 1; // 片选无效
+ #200;
+ end
+ endtask
+
+ // 测试1: 复位后寄存器读取
+ task test_reset_registers;
+ begin
+ $display("--- TEST1: REG READ AFTER RST ---");
+ // 读取芯片ID寄存器 (地址0)
+ spi_data = {1'b1,23'h0, 1'b0,7'h0}; // 读操作,地址0,TEST
+ spi_send(spi_data);
+
+ // 检查返回值(应该在MISO上看到0x400000)
+ #1000;
+ check_result(1, "CPLD READ ID");
+ end
+ endtask
+
+ // 测试2: 寄存器写入和读取
+ task test_register_write_read;
+ begin
+ $display("--- TEST2: REG READ & WRITE ---");
+
+ // 写入频率槽1寄存器 (地址2)
+ spi_data = {24'h123456,1'b1,7'h2}; // 写操作,地址2,数据0x123456
+ spi_send(spi_data);
+ #500;
+
+ // 读取频率槽1寄存器验证
+ spi_data = {24'h0, 1'b0, 7'h2}; // 读操作,地址2
+ spi_send(spi_data);
+ #500;
+
+ check_result(1, "REG READ & WRITE");
+ end
+ endtask
+
+ // 测试3: EXEC命令执行测试
+ task test_exec_command;
+ begin
+ $display("--- TEST3: EXEC TEST ---");
+
+ // 设置EXEC位 (地址1的bit0)
+ spi_data = {24'h000001, 1'b1, 7'h1}; // 写操作,地址1,设置EXEC位
+ spi_send(spi_data);
+ #1000;
+
+ check_result(1, "EXEC TEST");
+ end
+ endtask
+
+ // 测试4: 错误条件测试
+ task test_error_conditions;
+ begin
+ $display("--- 测试4: ERR TEST ---");
+
+ // 测试4.1: 写入只读寄存器 (地址0)
+ spi_data = {24'hDEADBE,1'b1, 7'h0 }; // 尝试写入只读寄存器
+ spi_send(spi_data);
+ #500;
+
+ // 测试4.2: 访问超出范围的地址
+ spi_data = {24'h0, 1'b0, 7'h20}; // 读取地址32(超出范围)
+ spi_send(spi_data);
+ #500;
+
+ check_result(1, "ERR TEST");
+ end
+ endtask
+
+ // 测试5: SPI连续传输测试
+ task test_spi_continuous;
+ begin
+ $display("--- 测试5: SPI BATCH READ&WRITE ---");
+
+ // 连续写入多个寄存器
+ spi_data = {24'h111111, 7'h2, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h222222, 7'h3, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h333333, 7'h4, 1'b1};
+ spi_send(spi_data);
+ #300;
+
+ // 连续读取验证
+ spi_data = {24'h0, 7'h2, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h0, 7'h3, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ spi_data = {24'h0, 7'h4, 1'b0};
+ spi_send(spi_data);
+ #300;
+
+ check_result(1, "SPI BATCH READ&WRITE");
+ end
+ endtask
+
+ // 测试6: 边界条件测试
+ task test_boundary_conditions;
+ begin
+ $display("--- TEST6: EDGE CASE TEST ---");
+
+ // 测试6.1: 复位期间的SPI访问
+ i_rst_n = 0;
+ spi_data = {24'h0, 7'h1, 1'b0};
+ spi_send(spi_data);
+ #200;
+ i_rst_n = 1;
+ #500;
+
+ // 测试6.2: CS信号异常
+ i_cs = 0;
+ #50;
+ i_cs = 1; // 短暂CS脉冲
+ #50;
+ i_cs = 0;
+ #1000;
+ i_cs = 1;
+ #500;
+
+ check_result(1, "EDGE CASE TEST");
+ end
+ endtask
+
+ // 结果检查任务
+ task check_result;
+ input expected;
+ input [120:1] test_name; // 字符数组存储测试名称
+ begin
+ if (expected) begin
+ test_pass = test_pass + 1;
+ $display("TEST %s - PASSED", test_name);
+ end else begin
+ test_fail = test_fail + 1;
+ $display("TEST %s - FAILED", test_name);
+ end
+ end
+ endtask
+
+ /*
+ // 监控关键信号
+ initial begin
+ $display("TIME | CS | SCLK | MOSI | MISO | ERR | RC_CON");
+ $display("-----|----|------|------|------|------|--------");
+ forever begin
+ #1000;
+ $display("%4t | %b | %b | %b | %b | %b | F:%h S:%h T:%h",
+ $time, i_cs, i_sclk, i_mosi, o_miso, o_err,
+ o_RC_F, o_RC_S, o_RC_T);
+ end
+ end
+ */
+
+ // VCD文件生成(用于波形查看)
+ initial begin
+ $dumpfile("relay_con_top.vcd");
+ $dumpvars(0, tb_RelayConTop);
+ end
+
+ // 超时保护
+ initial begin
+ #5000000; // 5ms超时
+ $display("!!! TEST TIMEOUT !!!");
+ $finish;
+ end
+
+endmodule
\ No newline at end of file