From c5df01f33df09a6dc2ec9e70bc36defa317e9e72 Mon Sep 17 00:00:00 2001 From: Jeremy Shen Date: Mon, 18 May 2026 13:54:11 +0800 Subject: [PATCH] Revert to default --- .gitignore | 233 +++++++++------ 2.FW/CPLD1/.floorplanner.ini | 14 + 2.FW/CPLD1/.gitignore | 3 + 2.FW/CPLD1/.run_manager.ini | 9 + 2.FW/CPLD1/.setting.ini | 4 + 2.FW/CPLD1/.spread_sheet.ini | 3 + 2.FW/CPLD1/.spreadsheet_view.ini | 76 +++++ 2.FW/CPLD1/BUS_Con.v | 215 ++++++++++++++ 2.FW/CPLD1/CPLD_Con.v | 190 ++++++++++++ 2.FW/CPLD1/NewExtIns_CPLD1.ccl | 1 + 2.FW/CPLD1/NewExtIns_CPLD1.ldf | 41 +++ 2.FW/CPLD1/NewExtIns_CPLD1.lpf | 247 ++++++++++++++++ 2.FW/CPLD1/Reg_file.v | 167 +++++++++++ 2.FW/CPLD1/RelayConTop.lst | 4 + 2.FW/CPLD1/RelayConTop.naf | 165 +++++++++++ 2.FW/CPLD1/RelayConTop.sym | Bin 0 -> 1040 bytes 2.FW/CPLD1/RelayConTop.tfi | 103 +++++++ 2.FW/CPLD1/RelayConTop.v | 139 +++++++++ 2.FW/CPLD1/RelayConTop_tf.v | 93 ++++++ 2.FW/CPLD1/piodrc.cfg | 0 2.FW/CPLD1/tb_RelayConTop.sv | 310 ++++++++++++++++++++ 2.FW/CPLD1/tb_RelayConTop/source_files.lst | 5 + 2.FW/CPLD2/.gitignore | 3 + 2.FW/CPLD2/.run_manager.ini | 9 + 2.FW/CPLD2/.setting.ini | 4 + 2.FW/CPLD2/.spread_sheet.ini | 3 + 2.FW/CPLD2/.spreadsheet_view.ini | 76 +++++ 2.FW/CPLD2/BUS_Con.v | 215 ++++++++++++++ 2.FW/CPLD2/CPLD_Con.v | 192 ++++++++++++ 2.FW/CPLD2/NewExtIns_CPLD2.ccl | 1 + 2.FW/CPLD2/NewExtIns_CPLD2.ldf | 38 +++ 2.FW/CPLD2/NewExtIns_CPLD2.lpf | 322 +++++++++++++++++++++ 2.FW/CPLD2/Reg_file.v | 167 +++++++++++ 2.FW/CPLD2/RelayConTop.v | 118 ++++++++ 2.FW/CPLD2/tb_RelayConTop.sv | 310 ++++++++++++++++++++ 2.FW/CPLD2/tb_RelayConTop/source_files.lst | 5 + 2.FW/CPLD3/.gitignore | 3 + 2.FW/CPLD3/.run_manager.ini | 9 + 2.FW/CPLD3/.setting.ini | 2 + 2.FW/CPLD3/.spread_sheet.ini | 3 + 2.FW/CPLD3/.spreadsheet_view.ini | 76 +++++ 2.FW/CPLD3/BUS_Con.v | 215 ++++++++++++++ 2.FW/CPLD3/CPLD_Con.v | 91 ++++++ 2.FW/CPLD3/NewExtIns_CPLD3.ccl | 1 + 2.FW/CPLD3/NewExtIns_CPLD3.ldf | 38 +++ 2.FW/CPLD3/NewExtIns_CPLD3.lpf | 29 ++ 2.FW/CPLD3/Reg_file.v | 165 +++++++++++ 2.FW/CPLD3/RelayConTop.v | 98 +++++++ 2.FW/CPLD3/piodrc.cfg | 0 2.FW/CPLD3/tb_RelayConTop.sv | 310 ++++++++++++++++++++ 50 files changed, 4436 insertions(+), 89 deletions(-) create mode 100644 2.FW/CPLD1/.floorplanner.ini create mode 100644 2.FW/CPLD1/.gitignore create mode 100644 2.FW/CPLD1/.run_manager.ini create mode 100644 2.FW/CPLD1/.setting.ini create mode 100644 2.FW/CPLD1/.spread_sheet.ini create mode 100644 2.FW/CPLD1/.spreadsheet_view.ini create mode 100644 2.FW/CPLD1/BUS_Con.v create mode 100644 2.FW/CPLD1/CPLD_Con.v create mode 100644 2.FW/CPLD1/NewExtIns_CPLD1.ccl create mode 100644 2.FW/CPLD1/NewExtIns_CPLD1.ldf create mode 100644 2.FW/CPLD1/NewExtIns_CPLD1.lpf create mode 100644 2.FW/CPLD1/Reg_file.v create mode 100644 2.FW/CPLD1/RelayConTop.lst create mode 100644 2.FW/CPLD1/RelayConTop.naf create mode 100644 2.FW/CPLD1/RelayConTop.sym create mode 100644 2.FW/CPLD1/RelayConTop.tfi create mode 100644 2.FW/CPLD1/RelayConTop.v create mode 100644 2.FW/CPLD1/RelayConTop_tf.v create mode 100644 2.FW/CPLD1/piodrc.cfg create mode 100644 2.FW/CPLD1/tb_RelayConTop.sv create mode 100644 2.FW/CPLD1/tb_RelayConTop/source_files.lst create mode 100644 2.FW/CPLD2/.gitignore create mode 100644 2.FW/CPLD2/.run_manager.ini create mode 100644 2.FW/CPLD2/.setting.ini create mode 100644 2.FW/CPLD2/.spread_sheet.ini create mode 100644 2.FW/CPLD2/.spreadsheet_view.ini create mode 100644 2.FW/CPLD2/BUS_Con.v create mode 100644 2.FW/CPLD2/CPLD_Con.v create mode 100644 2.FW/CPLD2/NewExtIns_CPLD2.ccl create mode 100644 2.FW/CPLD2/NewExtIns_CPLD2.ldf create mode 100644 2.FW/CPLD2/NewExtIns_CPLD2.lpf create mode 100644 2.FW/CPLD2/Reg_file.v create mode 100644 2.FW/CPLD2/RelayConTop.v create mode 100644 2.FW/CPLD2/tb_RelayConTop.sv create mode 100644 2.FW/CPLD2/tb_RelayConTop/source_files.lst create mode 100644 2.FW/CPLD3/.gitignore create mode 100644 2.FW/CPLD3/.run_manager.ini create mode 100644 2.FW/CPLD3/.setting.ini create mode 100644 2.FW/CPLD3/.spread_sheet.ini create mode 100644 2.FW/CPLD3/.spreadsheet_view.ini create mode 100644 2.FW/CPLD3/BUS_Con.v create mode 100644 2.FW/CPLD3/CPLD_Con.v create mode 100644 2.FW/CPLD3/NewExtIns_CPLD3.ccl create mode 100644 2.FW/CPLD3/NewExtIns_CPLD3.ldf create mode 100644 2.FW/CPLD3/NewExtIns_CPLD3.lpf create mode 100644 2.FW/CPLD3/Reg_file.v create mode 100644 2.FW/CPLD3/RelayConTop.v create mode 100644 2.FW/CPLD3/piodrc.cfg create mode 100644 2.FW/CPLD3/tb_RelayConTop.sv 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 0000000000000000000000000000000000000000..07bc9d089ec88a71bc5ef1e6d4eb041454751bdc GIT binary patch literal 1040 zcmZ9LKWGzC9LImZml)G3azm$1hhzxS;iV}UGdP$(s91A^h+>tO+5~!<<{i0WjW~!n zI7qp%ICT)|;BYvKI5}i+$ROgFv4}%Q5fQ)l(&RLO2cP^t-+TYx+na=60?kS$BP2(R zgiRxHB#4G$1(kr$QKk$?x@yBGx(f98;<%P_)t2^MqI;-@+!$BWuIlyL>#aV~Bh)2# z#`Tk^``fBZyQn(+Y}$vv(Ro1h233pq#??7j`F&qS;v?!q4yS$ZJY4U%Eus--8`6L> z)o(=eT5agAYUyqpapFYnMuSp}_0V@D{t%tfs=T_YD%aO?g`&J0r_Lf3VB}17k?Dk1 z?Ot!%!zDP2m*9#_X|1l*RK1joziq-xx(0uXDW%nx>+9G)kH+WwuuqsyYgH?$+*&^O z-{=R(*kTu%{YhqdHuD*org(?Ur%5J1n>j*eUwlR8aFSV>%~%4nav>|uq+Mfl6HzYu#5KH%H%n^T{cu@B%wehmL2_W$f=7>!S_;17)N z9iQ~%Jfr*R(R=uT@jJ)2EcOeh>g~>Yzofej?a`sg@=#PTfh=28;ooA8Bz7swF>`-V}f+c+bM{mJK8yF73A%8I(fCC;G_P`$hFzkRG{%Kf( TB`1?nKNi>m%#)3O5-.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