# Unet :::info ## SPEC [UnetWrapper_Code](https://github.com/yuchengwang1121/Unet) ![](https://hackmd.io/_uploads/HkXzPuKy6.png) ### Input Spec : 8-bit, 3 channel, 85,000 X 200,000 pixels ### Patch Spec : 128*128 patch (50% overlap) ### Output Spec : 8-bit, 128*128 patch p1, m0, mc * p1 : Output of UNET, Probability of droplet boundary * m0 : p0 >= 0.5, mask of droplet region * mc : (p0-p1) >= 0.5, mask of separated droplet region ![](https://hackmd.io/_uploads/Syez9dtka.png) ::: ## Q&A ### Questions * How to use the Flash read and write control signal line (Please give us a read and write example and wave file for observation) * If we want to connect the external circuit, What kind of connection is recommended? * MEMORY_INITIALIZATION_RADIX表示數據進制類型 * MEMORY_INITIALIZATION_VECTOR表示要儲存的數據 * Toggle DDR接口控制器將內部信號轉換為外部物理NAND引腳。 * What is the sub-module in Flash Channel Controller doing?(Data path ,Control Path, Command Dispatcher and Toggle DDR interface Controller) Is there a more detailed document that we can read and use it? * When Flash Channel Controller reads data, how to input addr to get data? Will the output be a burst or a page? * Why the size of DataPath and Control Path from Flash Channel Controller is 32*4 ? ### Answer * 寫操作 - iladata_program.ila * 讀操作 - iladata_page_read.ila/iladata_random_data_out.ila,讀取指令的輸出是一個頁面。讀操作包含兩個階段,頁讀取 / 隨機數據輸出。由於從NAND頁面將數據移動到頁緩衝區需要一些時間,因此在等待數據移動完成期間,軟體可以執行其他操作。 * 如果要連接外部電路,請將新的指令添加到ROM代碼(uProgROM_v2.0.coe)並修改指令調度程序。 * 指令在ROM代碼中定義 - cosm-plus-sys\cosm-plus-sys.sdk\run-gftl3\src\t4nsc_ucode.h。 * 據我所知,目前沒有關於NAND控制器的詳細設計文檔。 * 數據路徑和控制路徑的大小為32*4,因為通道控制器有4個通道。每個通道都有單獨的數據路徑和控制路徑。 * 數據路徑是64位匯流排,通過DMA接口傳輸頁數據。控制路徑是32位匯流排,用於傳輸指令。 * 當控制器讀取數據時,地址信息通過DQ[7:0]傳輸5個時鐘週期。當ALE為高電平且WE為下降沿時,地址被讀取。請查看ila文件iladata_page_read.ila。 * 請查收附上的讀寫控制信號線波形圖。Vivado通過「文件」->「導入」->「導入ILA數據」菜單顯示波形圖從ila文件中導入。 * 軟體通知指令調度程序特定NAND操作的ROM代碼的起始索引。指令調度程序解釋ROM代碼並執行NAND操作。 ## Waveform ### ILA waveform ```ila= close_hw //Report ERROr for initialize read_hw_ila_data C:/Users/WangYuCheng/Desktop/UNET/iladata_program.ila open_hw //read_hw_ila_data .ila position read_hw_ila_data C:/Users/WangYuCheng/Desktop/UNET/iladata_program.ila display_hw_ila_data ``` ### Write Data * **sys_top.v** * **sys_top_v2nfc_x_x t4nfc_(0~7)** * **NFC_Toggle_Top_DDR100** * **Nphy_Toggle_Top_DDR100** * **NPhy_Toggle_Physical_Output_DDR100** * **OSERDESE2 (Output Parallel-to-Serial Logic Resources)** * *[2:0] iPOReadEnable* * *[2:0] iPOWriteEnable* * *[31:0] iPODQ* * *[3:0] iPODQStrobe* * wire (connect **NPM_Toggle_Top_DDR100** & **NPhy_Toggle_Top_DDR100**) * *[7:0] wPOChipEnablePMPHY* * *wPOAddressLatchEnablePMPHY* * *wPOCommandLatchEnablePMPHY* ## Related Module ### OSERDESE2 ![](https://hackmd.io/_uploads/Hysm5_2_2.png =x500) #### Ports * CLK, CLKDIV : Serial & parallel CLK * RST : reset * D1 ~ D8 : Parallel data input port * OCE : HIGH active CLK Enable signal * OFB : Output feedback port * OQ : Serial data output * TBYTEIN : Byte group 3-state input * TBYTEOUT : Byte group 3-state output * TCE : HIGH active 3-state CLK Enable signal * TFB : Output feedback port * TQ : 3-state Ctrl module Output * T1 ~ T4 : 3-state Ctrl module Input * SHIFTIN1/SHIFTIN2 : Carry output for data width expansion. * SHIFTOUT1/SHIFTOUT2 : Carry input for data width expansion #### Parameter ![](https://hackmd.io/_uploads/Sy3ZbjpOn.png =x350) * DATA_RATE_OQ : 控制數據是以DDR或是以SDR作為輸出 * DATA_RATE_TQ : 3-state控制是以DDR或是以SDR作為輸出 * DATA_WIDTH : data的bit寬 * INIT_OQ : 輸出數據的初始化值 * INIT_TQ : 3-state控制輸出數據的初始化值 * SERDES_MODE : 主從模式 * SRVAL_OQ : 當SR使用時,OQ的輸出值 * SRVAL_TQ : 當SR使用時,TQ的輸出值 * TBYTE_CTL : 用於DDR3,3-state的字符操作使能 * TBYTE_SRC : 用於DDR3,3-state的字符源使能 * TRISTATE_WIDTH : 3-state的bit寬 ```verilog= OSERDESE2# ( .DATA_RATE_OQ ("DDR" ), //DDR, SDR .DATA_RATE_TQ ("BUF" ), //DDR, BUF, SDR .DATA_WIDTH (4 ), //Parallel data width(2-8, 10,14) .INIT_OQ (1'b0 ), //1'b0, 1'b1 .INIT_TQ (1'b0 ), //1'b0, 1'b1 .SERDES_MODE ("MASTER" ), //MASTER, SLAVE .SRVAL_OQ (1'b0 ), //1'b0, 1'b1 .SRVAL_TQ (1'b0 ), //1'b0, 1'b1 .TRISTATE_WIDTH (1 ) //3-state converter width(1, 4) ) ``` * **[More detail at p.161](https://docs.xilinx.com/v/u/en-US/ug471_7Series_SelectIO)** #### Run simulation * Use vivado -> Language Template -> Search"OSERDESE2" * Code for OSERDESE2 :::spoiler ```verilog= ////////////////////////////////////////////////////////////////////////////////// // Engineer: YuChengWang // Create Date: 2023/07/01 23:11:10 // Design Name: Test_of_OSERDESE2_write_function // Module Name: OSERDESE2_write // Revision 0.01 - File Created ////////////////////////////////////////////////////////////////////////////////// module OSERDESE2_write( input clk_serial, input clk_parallel, input rst_n, input [3:0] par_data, output ser_data ); OSERDESE2 #( .DATA_RATE_OQ("DDR"), // DDR, SDR .DATA_RATE_TQ("BUF"), // DDR, BUF, SDR .DATA_WIDTH(4), // Parallel data width (2-8,10,14) .INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1) .INIT_TQ(1'b0), // Initial value of TQ output (1'b0,1'b1) .SERDES_MODE("MASTER"), // MASTER, SLAVE .SRVAL_OQ(1'b0), // OQ output value when SR is used (1'b0,1'b1) .SRVAL_TQ(1'b0), // TQ output value when SR is used (1'b0,1'b1) // .TBYTE_CTL("FALSE"), // Enable tristate byte operation (FALSE, TRUE) // .TBYTE_SRC("FALSE"), // Tristate byte source (FALSE, TRUE) .TRISTATE_WIDTH(1) // 3-state converter width (1,4) ) OSERDESE2_inst ( .OFB(), // 1-bit output: Feedback path for data .OQ(ser_data), // 1-bit output: Data path output // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each) .SHIFTOUT1(), .SHIFTOUT2(), .TBYTEOUT(), // 1-bit output: Byte group tristate .TFB(), // 1-bit output: 3-state control .TQ(), // 1-bit output: 3-state control .CLK(clk_serial), // 1-bit input: High speed clock .CLKDIV(clk_parallel), // 1-bit input: Divided clock // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each) .D1(par_data[0]), .D2(par_data[1]), .D3(par_data[2]), .D4(par_data[3]), .D5(), .D6(), .D7(), .D8(), .OCE(1'b1), // 1-bit input: Output data clock enable .RST(~rst_n), // 1-bit input: Reset // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each) .SHIFTIN1(), .SHIFTIN2(), // T1 - T4: 1-bit (each) input: Parallel 3-state inputs .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TBYTEIN(1'b0), // 1-bit input: Byte group tristate .TCE(1'b0) // 1-bit input: 3-state clock enable ); endmodule ``` ::: * Code for OSERDESE2_tb :::spoiler ```verilog= `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Engineer: YuChengWang // Create Date: 2023/07/01 23:11:10 // Design Name: Test_of_OSERDESE2_write_function // Module Name: OSERDESE2_write // Revision 0.01 - File Created ////////////////////////////////////////////////////////////////////////////////// module OSERDESE2_write_tb( ); reg clk_serial; reg clk_parallel; reg rst_n; reg [3:0] par_data; wire ser_data; initial begin clk_serial <= 1'b1; clk_parallel <= 1'b0; rst_n <= 1'b0; par_data <= 4'b0; #180 rst_n <= 1'b1; end // set clk DATA_WIDTH=4, 2 Cycle always #5 clk_parallel = ~clk_parallel; always #2.5 clk_serial = ~clk_serial; //input data always #10 par_data <= $random%16; OSERDESE2_write OSERDESE2_write_inst( .clk_parallel (clk_parallel), .clk_serial (clk_serial), .rst_n (rst_n), .par_data (par_data), .ser_data (ser_data) ); endmodule ``` ::: ### Waveform ![](https://hackmd.io/_uploads/BytRlGxtn.png) * 第一個藍 : par給0101,並於下個clk_serial延遲後(第二藍處),將值透過ser_data由低至高輸出 ## Patch Size Compare * 使用$128*128$才可pipeline實作各layer,否則$256*256$只能一次做一個patch ![](https://hackmd.io/_uploads/SymSUOKyT.png) ## Implement on Vivado - BRAM for Base_Addr * Interface: 要在in/out put 的地方新增以下指令即可透過vivado之內建interface做包線 ![](https://hackmd.io/_uploads/HJVHZzOea.png =x300) ![](https://hackmd.io/_uploads/Bke9qf2yp.png =x150) ```verilog= //(* X_INTERFACE_INFO = "<interface vinv> <interface_name> <logical_port_name>" *) //Example (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARADDR" *) output [31:0]Unet_M00_AXI_araddr, ``` ### Rtl 模擬結果 * Unet_Wrapper+Bram之結果 * 接法 ![](https://hackmd.io/_uploads/HyrkiNT-a.png) * Address Editor(PS以及Unet_Wrapper) ![](https://hackmd.io/_uploads/HkmWjN6-p.png) ![](https://hackmd.io/_uploads/BJOfjN6ba.png) * 成功放置位置0x4580_0000 ![](https://hackmd.io/_uploads/BkjqklBGa.png) * [Bram Controller diagram](https://docs.xilinx.com/v/u/en-US/pg078-axi-bram-ctrl) ![](https://hackmd.io/_uploads/H1OzVxSGp.png) ### Synthesize 模擬結果 * 報錯 ![](https://hackmd.io/_uploads/SyGK__Tk6.png) * [解決辦法](https://blog.csdn.net/qq_44692266/article/details/114538905) ### Implement 模擬結果 * 報錯1 [解決辦法](https://blog.csdn.net/qq_42025108/article/details/124693736) ![](https://hackmd.io/_uploads/SyWv7jTkT.png) * 報錯2 [解決辦法](https://blog.csdn.net/qq_38376586/article/details/121994755) ![](https://hackmd.io/_uploads/HkYLow_e6.png) ### 成功畫面 ![](https://hackmd.io/_uploads/SyGOIq8Gp.png) ## 問題 ### Framwork端無法寫入Bram * Single-port : 只能一時刻寫,一時刻讀 * Simple Dual-port : 一端寫,一端讀 ![image](https://hackmd.io/_uploads/HJfLlahmp.png =x200) ![image](https://hackmd.io/_uploads/Sy5UlpnQp.png =x200) :::info ### 嘗試將Bram改SDport看看 [參考](https://zhuanlan.zhihu.com/p/208375629) ![image](https://hackmd.io/_uploads/SJW2NahX6.png) ::: ### 驗證是否能從BRAM正確取值 - PYNQ * 合成完以後點選【Set Up Debug】,並添加addrb、doutb和enb。分別讀出BRAM PORTB 地址、讀出數據以及始能 * 可以在net schematic時對感興趣線按右鍵選【Mark Debug】,之後再set up debug就不用慢慢拉 ![image](https://hackmd.io/_uploads/SJFEfWIET.png =x300) * 接著設置採樣深度,越深採集到的數據越多 ![image](https://hackmd.io/_uploads/rJ70MZLN6.png =x300) * 模擬結果 ![image](https://hackmd.io/_uploads/Bkn2IOiB6.png) ## Implement on Vivado - FLASH for Input_data ## bb ![image](https://hackmd.io/_uploads/SkRU3LO86.png) ![image](https://hackmd.io/_uploads/BkVwx17Pa.png)