chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

新手必看!FPGA的系統(tǒng)性學習

電子工程師 ? 來源:FPGA技術江湖 ? 作者:郝旭帥 ? 2020-09-28 11:52 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本系列將帶來FPGA的系統(tǒng)性學習,從最基本的數(shù)字電路基礎開始,最詳細操作步驟,最直白的言語描述,手把手的“傻瓜式”講解,讓電子、信息、通信類專業(yè)學生、初入職場小白及打算進階提升的職業(yè)開發(fā)者都可以有系統(tǒng)性學習的機會。

系統(tǒng)性的掌握技術開發(fā)以及相關要求,對個人就業(yè)以及職業(yè)發(fā)展都有著潛在的幫助,希望對大家有所幫助。后續(xù)會陸續(xù)更新 Xilinx 的 Vivado、ISE 及相關操作軟件的開發(fā)的相關內(nèi)容,學習FPGA設計方法及設計思想的同時,實操結合各類操作軟件,會讓你在技術學習道路上無比的順暢,告別技術學習小BUG卡破腦殼,告別目前忽悠性的培訓誘導,真正的去學習去實戰(zhàn)應用,這種快樂試試你就會懂的。話不多說,上貨。

高級設計:SDR SDRAM 驅動設計

作者:郝旭帥校對:陸輝

本篇實現(xiàn)基于叁芯智能科技的SANXIN -B01 FPGA開發(fā)板,以下為配套的教程,如有入手開發(fā)板,可以登錄官方淘寶店購買,還有配套的學習視頻。

隨機訪問存儲器(RAM)分為靜態(tài)RAM(SRAM)和動態(tài)RAM(DRAM)。由于動態(tài)存儲器存儲單元的結構非常簡單,所以它能達到的集成度遠高于靜態(tài)存儲器。但是動態(tài)存儲器的存取速度不如靜態(tài)存儲器快。

RAM的動態(tài)存儲單元是利用電容可以存儲電荷的原理制成的。由于存儲單元的機構能夠做得很簡單,所以在大容量、高集成度的RAM中得到了普遍的應用。但是由于電容的容量很小,而漏電流又不可能絕對等于零,所以電荷保存的時間有限。為了及時補充漏掉的電荷以避免存儲的信號丟失,必須定時地給電容補充電荷,通常將這種操作稱為刷新。

行列地址線被選中后,數(shù)據(jù)線(data_bit)直接和電容相連接。當寫入時,數(shù)據(jù)線給電容充放電;讀取時,電容將數(shù)據(jù)線拉高或者置低。

SDRAM 的全稱即同步動態(tài)隨機存儲器(Synchronous Dynamic Random Access Memory);這里的同步是指其時鐘頻率與對應控制器的系統(tǒng)時鐘頻率相同,并且內(nèi)部命令的發(fā)送與數(shù)據(jù)傳輸都是以該時鐘為基準;動態(tài)是指存儲陣列需要不斷的刷新來保證數(shù)據(jù)不丟失。

SDR SDRAM中的SDR是指單數(shù)據(jù)速率,即每一根數(shù)據(jù)線上,每個時鐘只傳輸一個bit的數(shù)據(jù)。SDR SDRAM的時鐘頻率可以達到100MHz以上,按照100MHz的速率計算,一片16位數(shù)據(jù)寬度的SDRSDRAM的讀寫數(shù)據(jù)帶寬可以達到1.6Gbit/s。

SANXIN – B01的開發(fā)板上有一個容量為256Mbit(16Mx 16bit)的SDRSDRAM(H57V2562GTR)。其內(nèi)部存儲時,分為了4個獨立的區(qū)域(BANK),每個bank為4Mx16bit的存儲空間;每個bank在存儲時,按照二維的方式進行存儲,利用行列來進行確定,有8192行(13bit地址線),有512列(9bit地址線),8192 x512為4M的存儲量。

在進行指定某個地址時,共需要2位bank地址,13位行地址,9位列地址,合計共24位地址。但是在SDRSDRAM的指定某個地址時,行地址和列地址不是同時給出,SDRSDRAM采用行列地址線復用,所以地址線合計為2(bank地址)+13(行、列地址復用)。

SDR SDRAM需要時鐘端和時鐘使能端。SDR SDRAM所有的操作都依靠于此時鐘;當時鐘使能端無效時,SDR SDRAM自動忽略時鐘上升沿。

SDR SDRAM擁有四個命令控制線,分別為CS、RAS、CAS、WE。組成的命令表如下:

在寫入數(shù)據(jù)時,有時會出現(xiàn)不想對某8bit進行寫入,就可以采用DQM進行控制。

SDRSDRAM的內(nèi)部機構為:

由于SDR SDRAM為DRAM,內(nèi)部的存儲都是靠電容進行保存數(shù)據(jù),電容的保持數(shù)據(jù)的時間為64ms,SDRSDRAM每次只能夠刷新一行,為了不丟失任何數(shù)據(jù),所以要保證64ms內(nèi),將所有的行都要刷新一遍。

SDR SDRAM支持讀寫的長度為1、2、4、8和一行(整頁)。

具體的SDR SDRAM的介紹可以查看手冊。下面只介紹幾個相對重要的時序圖。

在SDR SDRAM正常使用之前,需要進行初始化。初始化的時序圖如下:

在PRECHARGE時,A10為高,表示選中所有的bank;A10為低,表示選中BA0、BA1所指定的bank。初始化中,A10置高。

在LOAD MOOE REGISTER中,采用地址線進行配置模式寄存器。說明如下:

在模式配置中,利用CL(CAS Latency)表示列選通潛伏期,利用BL(Burst Length)表示突發(fā)長度。

SDR SDRAM中有內(nèi)部的刷新控制器和刷新的行計數(shù)器,外部控制器只需要保證在64ms之內(nèi)進行8192次刷新即可。

在進行PRECHARGE時,A10要為高電平。

SDR SDRAM中,我們可以在任意位置進行寫入。寫入的時序圖如下:

SDR SDRAM中,我們可以在任意位置進行讀出。讀出的時序圖如下:

在各個時序中的時序參數(shù)如下:

設計要求

設計一個突發(fā)長度為2,列選通潛伏期為2的SDR SDRAM的控制器。

設計分析

該控制器共有四部分功能,初始化、刷新、寫和讀。四部分的執(zhí)行控制采用一個模塊來控制。

SDR SDRAM必須要進行初始化,初始化只用執(zhí)行一次。然后啟動一個計時器,等計時器達到后,進行刷新。在刷新的間隔中,根據(jù)讀寫的要求進行讀寫。

四個模塊都會對SDR SDRAM的命令線和地址線進行控制,所以輸出時,采用多路選擇器對齊進行選擇輸出。

四個模塊按照對應的時序圖進行編寫代碼即可。

架構設計和信號說明

該控制器命名為sdr_drive。

pll_sdr(鎖相環(huán)模塊):產(chǎn)生驅動所需要的100MHz的時鐘(0度相位)、SDR SDRAM所需要的100MHz的時鐘(270度相位)、以及PLL鎖定信號當作系統(tǒng)復位使用。

timer(刷新計時器):當啟動計時器后,開始計時,當計時到規(guī)定時間后,輸出刷新請求,計數(shù)器直接清零計數(shù)計數(shù)。當控制器響應后,輸出清除信號后,刷新請求拉低。

refresh(刷新模塊)、init(初始化模塊)、sdr_write(寫模塊)、sdr_read(讀模塊):當啟動模塊后,按照規(guī)定的時序進行輸出即可,然后輸出完成信號。

sdr_ctrl(控制模塊):控制各個模塊協(xié)調(diào)工作。

mux4_1(四選一多路選擇器模塊):選擇對應的bus總線作為輸出。

*_bus的組成為:高四位為sdr_cs_n、sdr_ras_n、sdr_cas_n、sdr_we_n。然后是bank的兩位,后續(xù)為13位的sdr_addr。

sdr_drive_head聲明

將驅動中用到各種參數(shù)定義在該文件中。

`defineSDR_ADDR_WIDTH13`define SDR_COL_ADDR_WIDTH 9`define SDR_REFRESH_TIME 64_000_000 `define ADDR_WIDTH 2 + `SDR_ADDR_WIDTH + `SDR_COL_ADDR_WIDTH`define BUS_WIDTH 4 + 2 + `SDR_ADDR_WIDTH `define CMD_INH 4'b1000`define NOP 4'b0111`define ACT 4'b0011`define RD 4'b0101`define WR 4'b0100`define BT 4'b0110`define PREC 4'b0010`define REFR 4'b0001`define LMR 4'b0000 `define PU_DELAY 20_000`define Trp 3`define Trfc 7`define Tmrd 3`define Trcd 3`define Twr 3`define Tcl 2 `define CODE 13'b000_0_00_010_0_001`define REFRESH_TIME (`SDR_REFRESH_TIME/(2**`SDR_ADDR_WIDTH))/10

pll_sdr設計實現(xiàn)

該模塊為IP core,輸出0相位的100MHz(系統(tǒng)時鐘)和270相位的100MHz(SDR的時鐘)。系統(tǒng)設計中,信號在上升沿輸出;對于外部器件(相位調(diào)整為270),能夠較好的滿足建立和保持時間。

init設計實現(xiàn)

該模塊負責將SDR SDRAM進行初始化。上電延遲(PU_DELAY)設置為200us;預充電時間(Trp)設置為3個時鐘周期(30ns);自刷新時間(Trfc)設置為7個時鐘周期(70ns);模式寄存器應用時間(Tmrd)設置為3個時鐘周期(30ns);突發(fā)長度為2;列選通潛伏期為3。

按照對應的初始化的時序圖,做出如下設計。

本模塊采用狀態(tài)機的方式設計實現(xiàn)。

設計代碼為:

`include "../rtl/sdr_drive_head.v" module init ( input wire clk, input wire rst_n, input wire init_en, output reg init_done, output wire [`BUS_WIDTH - 1 : 0] init_bus); localparam IDLE = 7'b000_0001; localparam PUD = 7'b000_0010; localparam PRECHARGE = 7'b000_0100; localparam AUTOREFR1 = 7'b000_1000; localparam AUTOREFR2 = 7'b001_0000; localparam LMR_STATE = 7'b010_0000; localparam INITDONE = 7'b100_0000; reg [6:0] c_state; reg [6:0] n_state; wire [1:0] sdr_bank; reg [3:0] sdr_cmd; reg [`SDR_ADDR_WIDTH - 1 : 0] sdr_addr; reg [14:0] cnt; assign sdr_bank = 2'b00; assign init_bus = {sdr_cmd,sdr_bank,sdr_addr}; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) c_state <= IDLE; else c_state <= n_state; end always @ * begin case (c_state) IDLE : begin if (init_en == 1'b1) n_state = PUD; else n_state = IDLE; end PUD : begin if (cnt == `PU_DELAY - 1'b1) n_state = PRECHARGE; else n_state = PUD; end PRECHARGE : begin if (cnt == `Trp - 1'b1) n_state = AUTOREFR1; else n_state = PRECHARGE; end AUTOREFR1 : begin if (cnt == `Trfc - 1'b1) n_state = AUTOREFR2; else n_state = AUTOREFR1; end AUTOREFR2 : begin if (cnt == `Trfc - 1'b1) n_state = LMR_STATE; else n_state = AUTOREFR2; end LMR_STATE : begin if (cnt == `Tmrd - 1'b1) n_state = INITDONE; else n_state = LMR_STATE; end INITDONE : begin n_state = INITDONE; end default : n_state = IDLE; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_cmd <= `NOP; else case (c_state) IDLE : sdr_cmd <= `NOP; PUD : begin if (cnt == `PU_DELAY - 1'b1) sdr_cmd <= `PREC; else sdr_cmd <= `NOP; end PRECHARGE : begin if (cnt == `Trp - 1'b1) sdr_cmd <= `REFR; else sdr_cmd <= `NOP; end AUTOREFR1 : begin if (cnt == `Trfc - 1'b1) sdr_cmd <= `REFR; else sdr_cmd <= `NOP; end AUTOREFR2 : begin if (cnt == `Trfc - 1'b1) sdr_cmd <= `LMR; else sdr_cmd <= `NOP; end LMR_STATE : sdr_cmd <= `NOP; INITDONE : sdr_cmd <= `NOP; default : sdr_cmd <= `NOP; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) cnt <= 15'd0; else case (c_state) IDLE : cnt <= 16'd0; PUD : begin if (cnt < `PU_DELAY - 1'b1) cnt <= cnt + 1'b1; else cnt <= 16'd0; end PRECHARGE : begin if (cnt < `Trp - 1'b1) cnt <= cnt + 1'b1; else cnt <= 16'd0; end AUTOREFR1 : begin if (cnt < `Trfc - 1'b1) cnt <= cnt + 1'b1; else cnt <= 16'd0; end AUTOREFR2 : begin if (cnt < `Trfc - 1'b1) cnt <= cnt + 1'b1; else cnt <= 16'd0; end LMR_STATE : begin if (cnt < `Tmrd - 1'b1) cnt <= cnt + 1'b1; else cnt <= 16'd0; end INITDONE : cnt <= 16'd0; default : cnt <= 16'd0; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) init_done <= 1'b0; else if (c_state == LMR_STATE && cnt == `Tmrd - 1'b1) init_done <= 1'b1; else init_done <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_addr <= 0; else if (c_state == PUD && cnt == `PU_DELAY - 1'b1) sdr_addr[10] <= 1'b1; else if (c_state == AUTOREFR2 && cnt == `Trfc - 1'b1) sdr_addr <= `CODE; else sdr_addr <= 0; end endmodule

timer設計實現(xiàn)

SDRSDRAM內(nèi)部構造為DRAM,需要不間斷的刷新,要求64ms刷新一遍。每次刷新為一行,開發(fā)板上的SDRSDRAM共有8192行,平均需要7812.5ns刷新一次,我們選擇7810刷新一次。

到達規(guī)定的刷新時間時,控制器有可能正在進行其他的操作。在設計時,達到時間后,發(fā)出刷新請求,當外部執(zhí)行刷新后,將次請求清除。發(fā)出刷新請求的同時,計數(shù)器重新歸零計數(shù)。

`include "../rtl/sdr_drive_head.v" module timer ( input wire clk, input wire rst_n, input wire time_en, input wire req_clr, output reg refresh_req); reg [9:0] cnt; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) cnt <= 10'd0; else if (time_en == 1'b1 && cnt < `REFRESH_TIME - 1'b1) cnt <= cnt + 1'b1; else cnt <= 10'd0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) refresh_req <= 1'b0; else if (cnt == `REFRESH_TIME - 1'b1) refresh_req <= 1'b1; else if (req_clr == 1'b1) refresh_req <= 1'b0; else refresh_req <= refresh_req; end endmodule

refresh設計實現(xiàn)

該模塊負責刷新,按照對應的時序圖進行控制即可。

該模塊利用狀態(tài)機的方式實現(xiàn)。狀態(tài)轉移圖如下:

設計代碼為:

`include "../rtl/sdr_drive_head.v" module refresh ( input wire clk, input wire rst_n, input wire refresh_en, output reg refresh_done, output wire [`BUS_WIDTH - 1 : 0] refresh_bus); localparam IDLE = 5'b0_0001; localparam PRECHARGE = 5'b0_0010; localparam AUTOREFR1 = 5'b0_0100; localparam AUTOREFR2 = 5'b0_1000; localparam REFRDONE = 5'b1_0000; reg [4:0] c_state; reg [4:0] n_state; wire [1:0] sdr_bank; reg [3:0] sdr_cmd; reg [`SDR_ADDR_WIDTH - 1 : 0] sdr_addr; reg [3:0] cnt; assign sdr_bank = 2'b00; assign refresh_bus = {sdr_cmd,sdr_bank,sdr_addr}; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) c_state <= IDLE; else c_state <= n_state; end always @ * begin case (c_state) IDLE : begin if (refresh_en == 1'b1) n_state = PRECHARGE; else n_state = IDLE; end PRECHARGE : begin if (cnt == `Trp - 1'b1) n_state = AUTOREFR1; else n_state = PRECHARGE; end AUTOREFR1 : begin if (cnt == `Trfc - 1'b1) n_state = AUTOREFR2; else n_state = AUTOREFR1; end AUTOREFR2 : begin if (cnt == `Trfc - 1'b1) n_state = REFRDONE; else n_state = AUTOREFR2; end REFRDONE : begin n_state = IDLE; end default : n_state = IDLE; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_cmd <= `NOP; else case (c_state) IDLE : begin if (refresh_en == 1'b1) sdr_cmd <= `PREC; else sdr_cmd <= `NOP; end PRECHARGE : begin if (cnt == `Trp - 1'b1) sdr_cmd <= `REFR; else sdr_cmd <= `NOP; end AUTOREFR1 : begin if (cnt == `Trfc - 1'b1) sdr_cmd <= `REFR; else sdr_cmd <= `NOP; end AUTOREFR2 : sdr_cmd <= `NOP; REFRDONE : sdr_cmd <= `NOP; default : sdr_cmd <= `NOP; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) cnt <= 4'd0; else case (c_state) IDLE : cnt <= 4'd0; PRECHARGE : begin if (cnt < `Trp - 1'b1) cnt <= cnt + 1'b1; else cnt <= 4'd0; end AUTOREFR1 : begin if (cnt < `Trfc - 1'b1) cnt <= cnt + 1'b1; else cnt <= 4'd0; end AUTOREFR2 : begin if (cnt < `Trfc - 1'b1) cnt <= cnt + 1'b1; else cnt <= 4'd0; end REFRDONE : cnt <= 4'd0; default : cnt <= 4'd0; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) refresh_done <= 1'b0; else if (c_state == AUTOREFR2 && cnt == `Trfc - 1'b1) refresh_done <= 1'b1; else refresh_done <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_addr <= 0; else if (c_state == IDLE && refresh_en == 1'b1) sdr_addr[10] <= 1'b1; else sdr_addr <= 0; end endmodule

sdr_write設計實現(xiàn)

該模塊負責將外部的數(shù)據(jù)寫入到規(guī)定的地址中去。在SDRSDRAM中,每操作(讀寫)一次,都會引起該存儲位的漏電,每次結束時,可以進行預充電。SDR SDRAM提供了自動預充電的機制,在讀寫命令時,sdr_addr[10]=1,即可自動預充電。在設計時,應該要為自動預充電預留出足夠的時間。

根據(jù)對應的寫入時序圖,利用狀態(tài)機完成此設計。

設計代碼如下:

`include "../rtl/sdr_drive_head.v" module sdr_write ( input wire clk, input wire rst_n, input wire write_en, input wire [`ADDR_WIDTH - 1 : 0] wr_addr, input wire [31:0] wr_data, output reg [15:0] odq, output wire [`BUS_WIDTH - 1 : 0] wr_bus, output reg wr_done); localparam IDLE = 4'b0001; localparam ACT_STATE = 4'b0010; localparam WR1 = 4'b0100; localparam WR2 = 4'b1000; reg [3:0] c_state; reg [3:0] n_state; wire [1:0] sdr_bank; reg [3:0] sdr_cmd; reg [`SDR_ADDR_WIDTH - 1 : 0] sdr_addr; reg [14:0] cnt; assign sdr_bank = wr_addr[23:22]; assign wr_bus = {sdr_cmd,sdr_bank,sdr_addr}; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) c_state <= IDLE; else c_state <= n_state; end always @ * begin case (c_state) IDLE : begin if (write_en == 1'b1) n_state = ACT_STATE; else n_state = IDLE; end ACT_STATE : begin if (cnt == `Trcd - 1'b1) n_state = WR1; else n_state = ACT_STATE; end WR1 : n_state = WR2; WR2 : begin if (cnt == `Twr + `Trp - 1'b1) n_state = IDLE; else n_state = WR2; end default : n_state = IDLE; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_cmd <= `NOP; else if (c_state == IDLE && write_en == 1'b1) sdr_cmd <= `ACT; else if (c_state == ACT_STATE && cnt == `Trcd - 1'b1) sdr_cmd <= `WR; else sdr_cmd <= `NOP; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_addr <= 0; else if (c_state == IDLE && write_en == 1'b1) sdr_addr <= wr_addr[21:9]; else if (c_state == ACT_STATE && cnt == `Trcd - 1'b1) begin sdr_addr[10] <= 1'b1; sdr_addr[8:0] <= wr_addr[8:0]; end else sdr_addr <= 0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) cnt <= 4'd0; else if (c_state == ACT_STATE && cnt < `Trcd - 1'b1) cnt <= cnt + 1'b1; else if (c_state == WR2 && cnt < `Twr + `Trp - 1'b1) cnt <= cnt + 1'b1; else cnt <= 4'd0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) odq <= 16'd0; else if (c_state == ACT_STATE && cnt == `Trcd - 1'b1) odq <= wr_data[15:0]; else if (c_state == WR1) odq <= wr_data[31:16]; else odq <= 16'd0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) wr_done <= 1'b0; else if (c_state == WR2 && cnt < `Twr + `Trp - 1'b1) wr_done <= 1'b1; else wr_done <= 1'b0; end endmodule

sdr_read設計實現(xiàn)

該模塊負責從指定的地址中,將數(shù)據(jù)讀出。

按照對應的讀時序圖即可實現(xiàn)功能,本模塊采用狀態(tài)機方式實現(xiàn),狀態(tài)轉移圖如下:

設計代碼為:

module sdr_read ( input wire clk, input wire rst_n, input wire read_en, input wire [`ADDR_WIDTH - 1 : 0] rd_addr, input wire [15:0] sdr_dq, output reg [31:0] rd_data, output reg rd_done, output wire [`BUS_WIDTH - 1 : 0] rd_bus); localparam IDLE = 5'b00001; localparam ACT_STATE = 5'b00010; localparam READ_STATE = 5'b00100; localparam RD1 = 5'b01000; localparam RD2 = 5'b10000; reg [4:0] c_state; reg [4:0] n_state; wire [1:0] sdr_bank; reg [3:0] sdr_cmd; reg [`SDR_ADDR_WIDTH - 1 : 0] sdr_addr; reg [3:0] cnt; assign sdr_bank = rd_addr[23:22]; assign rd_bus = {sdr_cmd,sdr_bank,sdr_addr}; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) c_state <= IDLE; else c_state <= n_state; end always @ * begin case (c_state) IDLE : begin if (read_en == 1'b1) n_state = ACT_STATE; else n_state = IDLE; end ACT_STATE : begin if (cnt == `Trcd - 1'b1) n_state = READ_STATE; else n_state = ACT_STATE; end READ_STATE : begin if (cnt == `Tcl) n_state = RD1; else n_state = READ_STATE; end RD1 : n_state = RD2; RD2 : begin if (cnt == `Trp - 1'b1) n_state = IDLE; else n_state = RD2; end default : n_state = IDLE; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_cmd <= `NOP; else if (c_state == IDLE && read_en == 1'b1) sdr_cmd <= `ACT; else if (c_state == ACT_STATE && cnt == `Trcd - 1'b1) sdr_cmd <= `RD; else sdr_cmd <= `NOP; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) sdr_addr <= 0; else if (c_state == IDLE && read_en == 1'b1) sdr_addr <= rd_addr[21:9]; else if (c_state == ACT_STATE && cnt == `Trcd - 1'b1) begin sdr_addr[10] <= 1'b1; sdr_addr[8:0] <= rd_addr[8:0]; end else sdr_addr <= 0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) cnt <= 4'd0; else case (c_state) IDLE : cnt <= 4'd0; ACT_STATE : begin if (cnt < `Trcd - 1'b1) cnt <= cnt + 1'b1; else cnt <= 4'd0; end READ_STATE: begin if (cnt < `Tcl) cnt <= cnt + 1'b1; else cnt <= 4'd0; end RD1 : cnt <= 4'd0; RD2 : begin if (cnt < `Trp - 1'b1) cnt <= cnt + 1'b1; else cnt <= 4'd0; end default : cnt <= 4'd0; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rd_data <= 32'd0; else if (c_state == READ_STATE && cnt == `Tcl) rd_data[15:0] <= sdr_dq; else if (c_state == RD1) rd_data[31:16] <= sdr_dq; else rd_data <= rd_data; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rd_done <= 1'b0; else if (c_state == RD2 && cnt < `Trp - 1'b1) rd_done <= 1'b1; else rd_done <= 1'b0; end endmodule

mux4_1設計實現(xiàn)

該模塊負責選擇出對應的bus,然后將對應位作為輸出即可。

設計代碼為:

module mux4_1 ( input wire [`BUS_WIDTH - 1 : 0] init_bus, input wire [`BUS_WIDTH - 1 : 0] refresh_bus, input wire [`BUS_WIDTH - 1 : 0] wr_bus, input wire [`BUS_WIDTH - 1 : 0] rd_bus, input wire [1:0] mux_sel, output wire [1 : 0] sdr_bank, output wire [`ADDR_WIDTH - 1 : 0] sdr_addr, output wire sdr_cs_n, output wire sdr_ras_n, output wire sdr_cas_n, output wire sdr_we_n); reg [`BUS_WIDTH - 1 : 0] sdr_bus; assign sdr_cs_n = sdr_bus[18]; assign sdr_ras_n = sdr_bus[17]; assign sdr_cas_n = sdr_bus[16]; assign sdr_we_n = sdr_bus[15]; assign sdr_bank = sdr_bus[14:13]; assign sdr_addr = sdr_bus[12:0]; always @ * begin case (mux_sel) 2'b00 : sdr_bus = init_bus; 2'b01 : sdr_bus = refresh_bus; 2'b10 : sdr_bus = wr_bus; 2'b11 : sdr_bus = rd_bus; default : sdr_bus = init_bus; endcase end endmodule

sdr_ctrl設計實現(xiàn)

該模塊負責調(diào)度整個控制器,利用狀態(tài)機實現(xiàn)。

設計代碼為:

`include "../rtl/sdr_drive_head.v" module sdr_ctrl ( input wire clk, input wire rst_n, input wire wr_en, input wire rd_en, input wire [`ADDR_WIDTH - 1 : 0] addr, input wire [31:0] wdata, output reg [31:0] rdata, output reg rd_valid, output wire sdr_busy, output reg [1:0] mux_sel, output reg init_en, input wire init_done, output reg time_en, input wire refresh_req, output reg req_clr, output reg refresh_en, input wire refresh_done, output reg out_en, output reg write_en, output reg [`ADDR_WIDTH - 1 : 0] wr_addr, output reg [31:0] wr_data, input wire wr_done, output reg read_en, output reg [`ADDR_WIDTH - 1 : 0] rd_addr, input wire [31:0] rd_data, input wire rd_done); localparam IDLE = 6'b000_001; localparam INIT_STATE = 6'b000_010; localparam REFRESH_STATE = 6'b000_100; localparam NO_BUSY = 6'b001_000; localparam WR_STATE = 6'b010_000; localparam RD_STATE = 6'b100_000; reg [5:0] c_state; reg [5:0] n_state; reg wren; reg wren_clr; reg rden; reg rden_clr; reg [`ADDR_WIDTH - 1 : 0] addrr; reg [31:0] wdatar; reg busy; assign sdr_busy = busy | rd_en | wr_en; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) wren <= 1'b0; else if (wr_en == 1'b1) wren <= 1'b1; else if (wren_clr == 1'b1) wren <= 1'b0; else wren <= wren; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rden <= 1'b0; else if (rd_en == 1'b1) rden <= 1'b1; else if (rden_clr == 1'b1) rden <= 1'b0; else rden <= rden; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) wdatar <= 32'd0; else if (wr_en == 1'b1) wdatar <= wdata; else wdatar <= wdatar; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) addrr <= 0; else if (wr_en == 1'b1 || rd_en == 1'b1) addrr <= addr; else addrr <= addrr; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) c_state <= IDLE; else c_state <= n_state; end always @ * begin case (c_state) IDLE : n_state = INIT_STATE; INIT_STATE : begin if (init_done == 1'b1) n_state = REFRESH_STATE; else n_state = INIT_STATE; end REFRESH_STATE : begin if (refresh_done == 1'b1) n_state = NO_BUSY; else n_state = REFRESH_STATE; end NO_BUSY : begin if (refresh_req == 1'b1) n_state = REFRESH_STATE; else if (wren == 1'b1) n_state = WR_STATE; else if (rden == 1'b1) n_state = RD_STATE; else n_state = NO_BUSY; end WR_STATE : begin if (wr_done == 1'b1) n_state = NO_BUSY; else n_state = WR_STATE; end RD_STATE : begin if (rd_done == 1'b1) n_state = NO_BUSY; else n_state = RD_STATE; end default : n_state = IDLE; endcase end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) busy <= 1'b1; else if (c_state == NO_BUSY && wren == 1'b0 && rden == 1'b0 && refresh_req == 1'b0) busy <= rd_en | wr_en; else busy <= 1'b1; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) init_en <= 1'b0; else if (c_state == IDLE) init_en <= 1'b1; else init_en <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) time_en <= 1'b0; else if (c_state == INIT_STATE && init_done == 1'b1) time_en <= 1'b1; else time_en <= time_en; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) refresh_en <= 1'b0; else if (c_state == INIT_STATE && init_done == 1'b1) refresh_en <= 1'b1; else if (c_state == NO_BUSY && refresh_req == 1'b1) refresh_en <= 1'b1; else refresh_en <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) req_clr <= 1'b0; else if (c_state == NO_BUSY && refresh_req == 1'b1) req_clr <= 1'b1; else req_clr <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) write_en <= 1'b0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b1) write_en <= 1'b1; else write_en <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) out_en <= 1'b0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b1) out_en <= 1'b1; else if (c_state == WR_STATE && wr_done == 1'b1) out_en <= 1'b0; else out_en <= out_en; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) wr_addr <= 0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b1) wr_addr <= addrr; else wr_addr <= wr_addr; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) wr_data <= 0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b1) wr_data <= wdatar; else wr_data <= wr_data; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) wren_clr <= 1'b0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b1) wren_clr <= 1'b1; else wren_clr <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rden_clr <= 1'b0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b0 && rden == 1'b1) rden_clr <= 1'b1; else rden_clr <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) read_en <= 1'b0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b0 && rden == 1'b1) read_en <= 1'b1; else read_en <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rd_addr <= 0; else if (c_state == NO_BUSY && refresh_req == 1'b0 && wren == 1'b0 && rden == 1'b1) rd_addr <= addrr; else rd_addr <= rd_addr; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rdata <= 32'd0; else if (c_state == RD_STATE && rd_done == 1'b1) rdata <= rd_data; else rdata <= rdata; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rd_valid <= 1'b0; else if (c_state == RD_STATE && rd_done == 1'b1) rd_valid <= 1'b1; else rd_valid <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) mux_sel <= 2'b00; else case (c_state) IDLE : mux_sel <= 2'b00; INIT_STATE : begin if (init_done == 1'b1) mux_sel <= 2'b01; else mux_sel <= mux_sel; end REFRESH_STATE: mux_sel <= mux_sel; NO_BUSY : begin if (refresh_req == 1'b1) mux_sel <= 2'b01; else if (wren == 1'b1) mux_sel <= 2'b10; else if (rden == 1'b1) mux_sel <= 2'b11; else mux_sel <= mux_sel; end RD_STATE : mux_sel <= mux_sel; WR_STATE : mux_sel <= mux_sel; default : mux_sel <= 2'b00; endcase end endmodule

為了防止在進行刷新的起始部分丟失讀寫命令,所以在設計時,加入了緩存結構,只要有讀寫命令時,都會進行保存。在讀寫執(zhí)行時,才會清除此命令。

RTL仿真

為了能夠仿真此設計,需要用到SDR SDRAM的仿真模型。仿真模型在msim的sdr_sim_module中,將其修改為行線為13bit,列為9bit,每個bank有4194304個存儲空間。

在仿真時,在第二個bank,第五行,第10列,寫入一個隨機值。然后讀取出來。

仿真代碼為:

`timescale 1ns/1ps module sdr_drive_tb; reg clk; reg rst_n; wire sys_clk; wire sys_rst_n; wire sdr_busy; reg wr_en; reg rd_en; reg [23:0] addr; reg [31:0] wdata; wire [31:0] rdata; wire rd_valid; wire sdr_clk; wire sdr_cke; wire sdr_cs_n; wire sdr_ras_n; wire sdr_cas_n; wire sdr_we_n; wire [15:0] sdr_dq; wire [1:0] sdr_bank; wire [1:0] sdr_dqm; wire [12:0] sdr_addr; sdr_drive sdr_drive_inst( .clk (clk), .rst_n (rst_n), .sys_clk (sys_clk), .sys_rst_n (sys_rst_n), // local .sdr_busy (sdr_busy), .wr_en (wr_en), .rd_en (rd_en), .addr (addr), .wdata (wdata), .rdata (rdata), .rd_valid (rd_valid), // sdr .sdr_clk (sdr_clk), .sdr_cke (sdr_cke), .sdr_cs_n (sdr_cs_n), .sdr_ras_n (sdr_ras_n), .sdr_cas_n (sdr_cas_n), .sdr_we_n (sdr_we_n), .sdr_bank (sdr_bank), .sdr_addr (sdr_addr), .sdr_dqm (sdr_dqm), .sdr_dq (sdr_dq) ); mt48lc32m16a2 mt48lc32m16a2_inst( .Dq (sdr_dq), .Addr (sdr_addr), .Ba (sdr_bank), .Clk (sdr_clk), .Cke (sdr_cke), .Cs_n (sdr_cs_n), .Ras_n (sdr_ras_n), .Cas_n (sdr_cas_n), .We_n (sdr_we_n), .Dqm (sdr_dqm) ); initial clk = 1'b0; always # 10 clk = ~clk; initial begin rst_n = 1'b0; wr_en = 1'b0; rd_en = 1'b0; addr = {2'b01, 13'd5,9'd10}; wdata = 32'd0; # 201 rst_n = 1'b1; @ (negedge sdr_busy); @ (posedge sys_clk); # 2; wr_en = 1'b1; wdata = $random; @ (posedge sys_clk); # 2; wr_en = 1'b0; # 2000; @ (negedge sdr_busy); @ (posedge sys_clk); # 2; rd_en = 1'b1; @ (posedge sys_clk); # 2; rd_en = 1'b0; # 2000; $stop; end endmodule

這設置激勵時,將tb文件和仿真模型文件同時加入添加文件中。

在modelsim的報告界面會顯示出具體的配置信息以及讀寫信息。

從打印的報告中可以看出,在初始化時,列選通潛伏期為2,突發(fā)長度為2。在后續(xù)的讀寫時,在指定的位置,寫入了13604,后續(xù)的一個位置為4629;在讀出時,也正確的讀出了數(shù)據(jù)。

報告打印出寫入數(shù)據(jù),即認為寫入成功;報告打印出讀出數(shù)據(jù),只能證明控制器將數(shù)據(jù)讀出,并不表示控制器能把數(shù)據(jù)接收到。

通過控制輸出的rdata以及對應的rd_valid信號,確定讀出成功。在rdata中顯示為16進制,16進制的1215為十進制的4629;16進制的3524的為十進制的13604。證明讀數(shù)據(jù)接收正確。

板級測試

編寫控制器的上游模塊(sdr_drive_test_crtl),控制寫入和讀出。在固定的地址中addr = {2'b01, 13'd128, 9'd20},寫入一個固定的數(shù)字wdata = 32'h5a5aa5a5,然后讀出,進行驗證。

讀者在進行驗證時,可以采樣其他的地址或者數(shù)據(jù)進行驗證,且可以進行多次嘗試,保證設計正確。

該模塊采用狀態(tài)機設計實現(xiàn)。

設計代碼為:

`include "../rtl/sdr_drive_head.v" module sdr_drive_test_ctrl ( input wire clk, input wire rst_n, input wire sdr_busy, output reg wr_en, output reg rd_en, output wire [31:0] wdata, input wire rd_valid, input wire [31:0] rdata, output wire [`ADDR_WIDTH - 1 : 0] addr); localparam IDLE = 4'b0001; localparam WR_STATE = 4'b0010; localparam RD_STATE = 4'b0100; localparam TEST_DONE = 4'b1000; reg [3:0] c_state; reg [3:0] n_state; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) c_state <= IDLE; else c_state <= n_state; end always @ * begin case (c_state) IDLE : begin if (sdr_busy == 1'b0) n_state = WR_STATE; else n_state = IDLE; end WR_STATE : begin if (sdr_busy == 1'b0) n_state = RD_STATE; else n_state = WR_STATE; end RD_STATE : begin if (rd_valid == 1'b1 && rdata == 32'h5a5aa5a5) n_state = TEST_DONE; else n_state = RD_STATE; end TEST_DONE : n_state = TEST_DONE; default : n_state = IDLE; endcase end assign wdata = 32'h5a5aa5a5; assign addr = {2'b01, 13'd128, 9'd20}; always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) wr_en <= 1'b0; else if (c_state == IDLE && sdr_busy == 1'b0) wr_en <= 1'b1; else wr_en <= 1'b0; end always @ (posedge clk, negedge rst_n) begin if (rst_n == 1'b0) rd_en <= 1'b0; else if (c_state == WR_STATE && sdr_busy == 1'b0) rd_en <= 1'b1; else rd_en <= 1'b0; end endmodule

編寫測試頂層,模塊命名為sdr_drive_test,并且設置為頂層。

此模塊負責例化sdr_drive和sdr_drive_test_ctrl,完成連接功能,以此測試。

代碼為:

`include "../rtl/sdr_drive_head.v" module sdr_drive_test ( input wire clk, input wire rst_n, // sdr output wire sdr_clk, output wire sdr_cke, output wire sdr_cs_n, output wire sdr_ras_n, output wire sdr_cas_n, output wire sdr_we_n, output wire [1:0] sdr_bank, output wire [`SDR_ADDR_WIDTH - 1 : 0] sdr_addr, output wire [1:0] sdr_dqm, inout wire [15:0] sdr_dq); wire sys_clk; wire sys_rst_n; // local wire sdr_busy; wire wr_en; wire rd_en; wire [`ADDR_WIDTH - 1 : 0] addr; wire [31:0] wdata; wire [31:0] rdata; wire rd_valid; sdr_drive_test_ctrl sdr_drive_test_ctrl_inst( .clk (sys_clk), .rst_n (sys_rst_n), .sdr_busy (sdr_busy), .wr_en (wr_en), .rd_en (rd_en), .wdata (wdata), .rd_valid (rd_valid), .rdata (rdata), .addr (addr) ); sdr_drive sdr_drive_inst( .clk (clk), .rst_n (rst_n), .sys_clk (sys_clk), .sys_rst_n (sys_rst_n), // local .sdr_busy (sdr_busy), .wr_en (wr_en), .rd_en (rd_en), .addr (addr), .wdata (wdata), .rdata (rdata), .rd_valid (rd_valid), // sdr .sdr_clk (sdr_clk), .sdr_cke (sdr_cke), .sdr_cs_n (sdr_cs_n), .sdr_ras_n (sdr_ras_n), .sdr_cas_n (sdr_cas_n), .sdr_we_n (sdr_we_n), .sdr_bank (sdr_bank), .sdr_addr (sdr_addr), .sdr_dqm (sdr_dqm), .sdr_dq (sdr_dq) ); endmodule

經(jīng)過綜合分析后,進行分配管腳。在分配管腳后,需要將雙功能管腳中的NCEO設置為普通用戶IO。如果不設置,將會出現(xiàn)如下錯誤:

右擊器件名稱,選擇DEVICE。

選擇device and pin option。

選擇dual – purpose pins。

將nceo設置為useas regular IO。

點擊OK,進行編譯即可。

連接上開發(fā)板,啟動邏輯分析儀。

將采樣時鐘選擇為,sys_clk(PLL的c0)。采樣深度選擇為1K。

添加觀測信號如下,將wr_en的上升沿設置為觸發(fā)條件。

經(jīng)過保存,重新形成配置文件后,進行下板測試。

下板后,按下復位。等待波形觸發(fā)。

通過邏輯分析儀,就可以看出可以正確的寫入和讀出數(shù)據(jù)。

讀者也可以進行嘗試一次性寫入多個數(shù)據(jù),然后進行讀出,進行驗證設計的正確性。

- End -

原文標題:FPGA零基礎學習:SDR SDRAM 驅動設計

文章出處:【微信公眾號:FPGA技術江湖】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1659

    文章

    22369

    瀏覽量

    633125
  • 驅動
    +關注

    關注

    12

    文章

    1939

    瀏覽量

    88406
  • SDR
    SDR
    +關注

    關注

    7

    文章

    241

    瀏覽量

    51858

原文標題:FPGA零基礎學習:SDR SDRAM 驅動設計

文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術江湖】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    FPGA 入門必看:Verilog 與 VHDL 編程基礎解析!

    很多開發(fā)者第一次接觸FPGA,都會有同樣的疑問:FPGA是硬件,不是軟件,怎么寫程序?答案就是用硬件描述語言(HDL),最常用的就是Verilog和VHDL。今天,我們就帶你入門,搞清楚FPGA編程
    的頭像 發(fā)表于 01-19 09:05 ?223次閱讀
    <b class='flag-5'>FPGA</b> 入門<b class='flag-5'>必看</b>:Verilog 與 VHDL 編程基礎解析!

    資料] 汽車軟件質量躍遷的系統(tǒng)性路徑:基于ISO 26262標準的單元測試體系重構與中日實踐深度對比(2026學術研究報告)

    各位伙伴,請問一個問題,[資料] 汽車軟件質量躍遷的系統(tǒng)性路徑:基于ISO 26262標準的單元測試體系重構與中日實踐深度對比(2026學術研究報告),這份數(shù)據(jù)誰有源參考文獻,有酬感謝
    發(fā)表于 01-08 10:09

    嵌入式入門必看!迅為RK3568?V2.0升級,新手也能輕松玩轉

    嵌入式入門必看!迅為RK3568?V2.0升級,新手也能輕松玩轉
    的頭像 發(fā)表于 10-28 13:26 ?315次閱讀
    嵌入式入門<b class='flag-5'>必看</b>!迅為RK3568?V2.0升級,<b class='flag-5'>新手</b>也能輕松玩轉

    ASP4644芯片在雷達FPGA供電系統(tǒng)中的適配與性能分析

    本文系統(tǒng)性地分析了國科安芯推出的ASP4644芯片在雷達FPGA供電系統(tǒng)中的適配與性能表現(xiàn)。
    的頭像 發(fā)表于 10-14 17:09 ?548次閱讀

    新手必看:電池包氣密檢測儀操作入門指南-岳信儀器

    對于剛接觸電池包氣密檢測儀的新手來說,了解其操作方法至關重要。下面就為大家詳細介紹電池包氣密檢測儀的操作入門知識。(1)操作前準備在開啟檢測儀前,要確保設備放置于平穩(wěn)、干燥且通風良好的環(huán)境,避免
    的頭像 發(fā)表于 09-12 11:39 ?424次閱讀
    <b class='flag-5'>新手</b><b class='flag-5'>必看</b>:電池包氣密<b class='flag-5'>性</b>檢測儀操作入門指南-岳信儀器

    Linux系統(tǒng)性能優(yōu)化技巧

    經(jīng)過10年一線運維經(jīng)驗,我發(fā)現(xiàn)大多數(shù)工程師只掌握了Linux優(yōu)化的冰山一角。今天分享的這些秘技,能讓你的系統(tǒng)性能提升200%以上!
    的頭像 發(fā)表于 08-27 14:34 ?798次閱讀

    新手必看:汽車散熱器氣密檢測儀的正確操作步驟

    對于汽車維修新手或者剛接觸汽車散熱器檢測的人來說,掌握汽車散熱器氣密檢測儀的正確操作步驟至關重要。接下來就為大家詳細介紹。(1)操作前準備在使用汽車散熱器氣密檢測儀之前,要做好充分的準備工作
    的頭像 發(fā)表于 08-27 14:25 ?560次閱讀
    <b class='flag-5'>新手</b><b class='flag-5'>必看</b>:汽車散熱器氣密<b class='flag-5'>性</b>檢測儀的正確操作步驟

    廚房電器EMC整改:從測試到優(yōu)化的系統(tǒng)性解決方案

    南柯電子|廚房電器EMC整改:從測試到優(yōu)化的系統(tǒng)性解決方案
    的頭像 發(fā)表于 08-12 11:29 ?709次閱讀
    廚房電器EMC整改:從測試到優(yōu)化的<b class='flag-5'>系統(tǒng)性</b>解決方案

    Linux系統(tǒng)性能調(diào)優(yōu)方案

    關鍵要點預覽:本文將深入解析Linux系統(tǒng)性能瓶頸的根本原因,提供可直接落地的調(diào)優(yōu)方案,讓你的系統(tǒng)性能提升30-50%!
    的頭像 發(fā)表于 08-06 17:49 ?750次閱讀

    汽車導航系統(tǒng)EMC整改:工程師必看,成本降低40%的秘訣

    南柯電子|汽車導航系統(tǒng)EMC整改:工程師必看,成本降低40%的秘訣
    的頭像 發(fā)表于 07-22 11:07 ?538次閱讀

    PLL技術在FPGA中的動態(tài)調(diào)頻與展頻功能應用

    隨著現(xiàn)代電子系統(tǒng)的不斷發(fā)展,時鐘管理成為影響系統(tǒng)性能、穩(wěn)定性和電磁兼容(EMI)的關鍵因素之一。在FPGA設計中,PLL因其高精度、靈活性和可編程
    的頭像 發(fā)表于 06-20 11:51 ?2452次閱讀
    PLL技術在<b class='flag-5'>FPGA</b>中的動態(tài)調(diào)頻與展頻功能應用

    通信設備EMC整改:從測試到優(yōu)化的系統(tǒng)性解決方案

    深圳南柯電子|通信設備EMC整改:從測試到優(yōu)化的系統(tǒng)性解決方案
    的頭像 發(fā)表于 06-16 11:10 ?620次閱讀

    嵌入式開發(fā):高門檻的系統(tǒng)性工程與 996 的行業(yè)困局

    嵌入式開發(fā)的門檻,往往被培訓機構和表象所掩蓋。許多人誤以為 “用 C 語言寫個跑在 ARM 上的程序” 就是嵌入式,實則連皮毛都未觸及。真正的嵌入式開發(fā)是硬件與軟件深度融合的系統(tǒng)性工程,需跨越三重壁壘
    的頭像 發(fā)表于 04-09 11:06 ?821次閱讀
    嵌入式開發(fā):高門檻的<b class='flag-5'>系統(tǒng)性</b>工程與 996 的行業(yè)困局

    進群免費領FPGA學習資料!數(shù)字信號處理、傅里葉變換與FPGA開發(fā)等

    進群免費領FPGA學習資料啦!小編整理了數(shù)字信號處理、傅里葉變換與FPGA開發(fā)等FPGA必看資料,需要的小伙伴可以加小助手(微信:elecf
    發(fā)表于 04-07 16:41

    氣密檢測儀參數(shù)調(diào)試全攻略:新手必看的5大核心技巧

    氣密檢測儀是工業(yè)品檢中的關鍵設備,但參數(shù)調(diào)試常讓新手頭疼。別擔心!今天用5分鐘帶你掌握調(diào)試核心技巧,輕松避開“漏氣焦慮”!一、調(diào)試前的準備工作明確檢測標準:先確認產(chǎn)品允許的泄漏值(如≤0.5kPa
    的頭像 發(fā)表于 03-14 15:07 ?1160次閱讀
    氣密<b class='flag-5'>性</b>檢測儀參數(shù)調(diào)試全攻略:<b class='flag-5'>新手</b><b class='flag-5'>必看</b>的5大核心技巧