浏阳seo/seo是什么意思知乎
一、基本知识
SDRAM : 即同步动态随机存储器(Synchronous Dynamic Random Access Memory), 同步是指其时钟频率与对应控制器(CPU/FPGA)的系统时钟频率相同,并且内部命令 的发送与数据传输都是以该时钟为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机指数据的读取和写入可以随机指定地址,而不是必须按照严格的线性次序变化。
SDRAM 使用电容的电荷存储特性存储数据,而 SRAM使用CMOS晶体管存储数据,这决定了SDRAM的运行功耗要远远低于SRAM。由于使用晶体管存储数据,要能够正确的存储一位数据,需要最少6个晶体管。因此,从芯片面积上来说,单片SRAM芯片的容量不可能做到很高。
通常情况下,SDRAM 是拥有四个 BANK 的动态刷新存储器,存储器工作在 3.3V 的电 压下,拥有一个同步接口,SDRAM 的所有信号都在时钟信号的上升沿被寄存。对于 SDRAM 的读写是以突发的方式进行的,对 sdram 的获取(读或者写)是从一个指定的地址开始,并按照编程好的数量(长度)的地址,以编程好的数据顺序读写数据。
存取原理:先通过行地址打开行地址线,后通过列地址线打开列地址,便实现把电容与数据线连通,实现读/写操作。
打开行地址需要tRCD时间,后才能打开列地址。tRCD可查手册,计算需要多少个对应频率的时钟的延迟,进行设计。
打开列地址后,如果是读操作,需要CL(CAS READ LATENCY)个时钟周期才会出数据,如果是写操作,则数据需要同时送出,不用CL。
不同型号的sdram:命令、时序参数有区别
二、型号MT48LC16M16A2的sdram
引脚:
对于sdram的控制,通过CS_N、RAS_N、CAS_N、WE_N四个引脚来控制,故记这四个引脚组成的状态为控制命令cmd。
通过这个表来设置cmd。
1.时序设计
控制sdram只需要结合时序图和命令表,通过线性序列机和状态机来设计就可以。
1.上电初始化:通过计数器使sdram处于nop状态 不少于100us后,发出一个precharge命令,经过tRP时间(一直处于nop,下同),发出一个autorefresh命令,经过tRFC时间,再autorefresh一次,经过tRFC时间,便可发出load mode register命令配置模式寄存器。
模式寄存器设置规则如下:
2.读/写命令:
器件手册给出了包括读/写在内的多种命令的时序图,根据时序图进行设计即可,比如常用的:
2.代码设计
类似IIC协议和SPI协议,依旧是状态机加线性序列机的形式来是实现。最底层用状态机实现每种状态需要的操作,中间层用线性序列机实现一个完整的读/写/其他操作需要经过几种状态的跳转。故先定义状态和命令cmd。
注意,设计时仍然需要注意时钟问题,给sdram的时钟是在上升沿读取数据,所以输出的数据在上升沿应该是稳定的,具体可以通过设计与读写两个时钟的移相来实现。
module sdram_driver(input clk ,input rst_n ,input write_sig ,input read_sig ,input initial_sig ,input [12:0]write_addr ,input [1:0]write_bank ,input [12:0]read_addr ,input [1:0]read_bank ,output reg [3:0]cmd ,output reg [1:0]bank ,output reg [12:0]addr ,output reg [11:0]mode ,output reg cke_ctrl ,output reg [1:0]dqm_ctrl ,output reg initial_done ,output reg [15:0]read_data ,output reg trans_done ,inout [15:0]DQ
);//状态参数
localparam nop1 = 4'b1000 ; //空闲态:禁止命令
localparam nop2 = 4'b0111 ; //空闲态:空命令
localparam active = 4'b0011 ; //选bank与行
localparam read = 4'b0101 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam write = 4'b0100 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam burst_terminate = 4'b0110 ; //突发中止
localparam precharge = 4'b0010 ; //关闭行,预充电
localparam refresh = 4'b0001 ; //刷新
localparam load_mode_register = 4'b0000 ; //a0 - a11 tmrd// mode register
localparam M9_BL_mode = 1'b0 ; //length
localparam M9_SL_mode = 1'b1 ; //single
localparam M87_SO_mode = 2'b00 ;
localparam M654_CAS_2 = 3'b010 ;//CL
localparam M654_CAS_3 = 3'b011 ;//CL
localparam M3_seq = 1'b0 ;
localparam M3_intl = 1'b1 ;
localparam M210_BL_1 = 3'b000 ;//be able to replace single read/write (M9)
localparam M210_BL_2 = 3'b001 ;
localparam M210_BL_4 = 3'b010 ;
localparam M210_BL_8 = 3'b011 ;
localparam M210_BL_full = 3'b111 ;// read with auto precharge ?
localparam auto_precharge = 1 ;
wire rd_with_auto , wr_with_auto ;
assign rd_with_auto = auto_precharge ;
assign wr_with_auto = auto_precharge ;reg [15:0]cmd_cnt ;
always@( posedge clk or negedge rst_n )
if(!rst_n)begincmd_cnt <= 0 ;cmd <= nop2 ;bank <= 0 ;addr <= 0 ;mode <= 0 ;cke_ctrl <= 0 ;dqm_ctrl <= 0 ; trans_done <= 0 ;initial_done<= 0 ;read_data <= 0 ;end
else if(initial_sig)begincmd_cnt <= cmd_cnt + 1 ;case(cmd_cnt)1:cmd <= nop2 ;//delay > 100 us10005: begin cke_ctrl <= 1 ; end10010: begin cmd <= precharge ; addr[10] = 1 ; end //precharge all banks : tRP >= 20ns (2T)10011: begin cmd <= nop2 ; end10015: begin cmd <= refresh ; cke_ctrl <= 1 ; end //auto refresh : >= 2T(RFC) ; T(RFC) >= 66ns 1T(auto)(256Mb) = 819210016: begin cmd <= nop2 ; end10026: begin cmd <= refresh ; cke_ctrl <= 1 ; end // 10027: begin cmd <= nop2 ; end // 10040: begin cmd <= load_mode_register ; bank <= 0 ; mode <= { 2'b00 , M9_BL_mode , M87_SO_mode , M654_CAS_3 , M3_seq , M210_BL_4 } ;end //set mode :t(mrd) = 2t(ck) = 2*6 = 12 ns10041: begin cmd <= nop2 ; end10045: begin initial_done <= 1 ; end10046: begin cmd_cnt <= 0 ; enddefault:cmd <= nop2 ; endcaseend
else if(initial_done)beginif(write_sig)beginif(wr_with_auto)begincmd_cnt <= cmd_cnt + 1 ;case(cmd_cnt)1:begin cmd <= active ; bank <= write_bank ; addr <= write_addr ; end4:begin cmd <= write ; bank <= write_bank ; addr <= {write_addr[12:11],1'b1,write_addr[9:0]}; end10:begin trans_done <= 1 ; cmd_cnt <= 0 ;enddefault:cmd<=nop2;endcaseendelse if(~wr_with_auto)begincmd_cnt <= cmd_cnt + 1 ;case(cmd_cnt)1:begin cmd <= active ; bank <= write_bank ; addr <= write_addr ; end4:begin cmd <= write ; bank <= write_bank ; addr <= {write_addr[12:11],1'b1,write_addr[9:0]}; end9:begin cmd <= precharge ; addr[10] = 1 ;end12:begin trans_done <= 1 ; cmd_cnt <= 0 ;enddefault:cmd<=nop2;endcaseend endelse if(read_sig)beginif( rd_with_auto )begincmd_cnt <= cmd_cnt + 1 ;case(cmd_cnt)1:begin cmd <= active ; bank <= read_bank ; addr <= read_addr ; end4:begin cmd <= read ; bank <= read_bank ; addr <= {read_addr[12:11],1'b1,read_addr[9:0]}; end //addr10 control auto charge9:begin read_data <= DQ ; end10:begin read_data <= DQ ; end11:begin read_data <= DQ ; end12:begin read_data <= DQ ; end13:begin trans_done<= 1 ; cmd_cnt <= 0 ; enddefault:begin cmd <= nop2 ;read_data <= DQ ;endendcaseendelse if( ~rd_with_auto )begincmd_cnt <= cmd_cnt + 1 ;case(cmd_cnt)1:begin cmd <= active ; bank <= read_bank ; addr <= read_addr ; end4:begin cmd <= read ; bank <= read_bank ; addr <= {read_addr[12:11],1'b0,read_addr[9:0]}; end //addr10: control auto charge9:begin read_data <= DQ ; end10:begin read_data <= DQ ; end11:begin read_data <= DQ ; cmd <= precharge ; addr[10] = 1 ; end //precharge12:begin read_data <= DQ ; end14:begin trans_done<= 1 ; cmd_cnt <= 0 ; enddefault:cmd <= nop2 ;endcaseendendelsebegincmd <= nop2 ;cmd_cnt <= 0 ;trans_done<= 0 ;endend
elsebegincmd_cnt <= 0 ;endendmodule
//-75 100MHz CL = 2 setup = 1.5 hold = 0.8 上升沿读写数据//
// 100MHz : T = 10ns //
// tRP >= 20ns ; T(RFC) >= 66ns ; t(mrd) = 12 ns
// 这里实现 普通的写和读 ;有特殊要求的根据手册进行cmd修改即可module sdram_ctrl(input fpga_clk ,input rst_n ,input write_sig ,input read_sig ,input [12:0]write_addr ,input [1:0]write_bank ,input [15:0]write_data ,input [12:0]read_addr ,input [1:0]read_bank , output trans_done ,output [15:0]read_data ,output sclk ,output CKE ,output CS_N ,output RAS_N ,output CAS_N ,output WE_N ,output [1:0]DQM ,//高电平时屏蔽output [12:0]SA ,//A12 - A0output [1:0]BA ,inout [15:0]DQ
);wire clk_100m;
wire clk_100m_90shift ;
pll pll_inst(.inclk0(fpga_clk),.c0(clk_100m),.c1(clk_100m_90shift));
assign sclk = clk_100m_90shift ;//read / write signal catch
reg write_sig_reg ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)write_sig_reg <= 0 ;
elsewrite_sig_reg <= write_sig ;reg read_sig_reg ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)read_sig_reg <= 0 ;
else read_sig_reg <= read_sig ;reg write_signal ;
reg read_signal ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)write_signal <= 0 ;
else if( write_sig & (!write_sig_reg ) )write_signal <= 1 ;
else if(trans_done)write_signal <= 0 ;always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)read_signal <= 0 ;
else if( read_sig & (!read_sig_reg ) )read_signal <= 1 ;
else if(trans_done)read_signal <= 0 ; // initial sdram
reg [5:0]initial_cnt ;
wire initial_done ;
always@(posedge clk_100m or negedge rst_n)
if(!rst_n)initial_cnt <= 0 ;
else if( initial_cnt < 50 )initial_cnt <= initial_cnt + 1 ;
elseinitial_cnt <= initial_cnt ;reg initial_sig ;
always@(posedge clk_100m or negedge rst_n)
if(!rst_n)initial_sig <= 0 ;
else if(initial_cnt == 48)initial_sig <= 1 ;
else if(initial_done)initial_sig <= 0 ;wire [3:0]cmd ;
wire [1:0]bank ;
wire [12:0]addr ;
wire [11:0]mode ;
wire cke_ctrl ;
wire [1:0]dqm_ctrl ;
sdram_driver sdram_driver_inst(.clk(clk_100m) ,.rst_n(rst_n) ,.write_sig(write_signal) ,.read_sig(read_signal) ,.initial_sig(initial_sig),.write_addr(write_addr) ,.write_bank(write_bank) ,.read_addr(read_addr) ,.read_bank(read_bank) ,.cmd(cmd) ,.bank(bank) ,.addr(addr) ,.mode(mode) ,.cke_ctrl(cke_ctrl) ,.dqm_ctrl(dqm_ctrl) ,.initial_done(initial_done),.read_data(read_data) ,.trans_done(trans_done) ,.DQ(DQ)
); sdram_underlying_logic sdram_underlying_logic_inst(.clk(clk_100m) ,.rst_n(rst_n) ,.mode(mode),//A11 -A0.cmd(cmd) ,.cke_ctrl(cke_ctrl) ,.bank(bank) ,.addr(addr) ,.write_data(write_data) ,.dqm_ctrl(dqm_ctrl),.CKE(CKE) ,.CS_N(CS_N) ,.RAS_N(RAS_N) ,.CAS_N(CAS_N) ,.WE_N(WE_N) ,.DQM(DQM) ,//高电平时屏蔽.SA(SA) ,//A12 - A0.BA(BA) ,.DQ(DQ)
);endmodule
module sdram_underlying_logic(input clk ,input rst_n ,input [11:0]mode,//A11 -A0input [3:0]cmd ,input cke_ctrl ,input [1:0]bank ,input [12:0]addr ,input [15:0]write_data ,input [1:0]dqm_ctrl,output reg CKE ,output reg CS_N ,output reg RAS_N ,output reg CAS_N ,output reg WE_N ,output reg[1:0]DQM ,//高电平时屏蔽output reg[12:0]SA ,//A12 - A0output reg [1:0]BA ,inout [15:0]DQ
);reg DQ_ctrl ;
reg [15:0]DQ_out ;
assign DQ = (DQ_ctrl ? DQ_out : 16'hzzzz) ;/////状态参数
localparam nop1 = 10'b1000000000 ; //空闲态:禁止命令
localparam nop2 = 10'b0100000000 ; //空闲态:空命令
localparam active = 10'b0010000000 ; //选bank与行
localparam read = 10'b0001000000 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam write = 10'b0000100000 ; //选bank和列,启动突发读 ,最后一位为屏蔽位
localparam burst_terminate = 10'b0000010000 ; //突发中止
localparam precharge = 10'b0000001000 ; //关闭行,预充电
localparam auto_refresh = 10'b0000000100 ; //自动刷新
localparam self_refresh = 10'b0000000010 ; //自刷新
localparam load_mode_register = 10'b0000000001 ; //加载模式寄存器reg [9:0]state ;//状态机
always@(posedge clk or negedge rst_n)
if(!rst_n)state <= nop2 ;
else if( cmd[3] )state <= nop1 ;
else if( cmd == 4'b0111 )state <= nop2 ;
else if( cmd == 4'b0011 )state <= active ;
else if( cmd == 4'b0101 )state <= read ;
else if( cmd == 4'b0100 )state <= write ;
else if( cmd == 4'b0110 )state <= burst_terminate ;
else if( cmd == 4'b0010 )state <= precharge ;
else if( cmd == 4'b0001 )beginif(cke_ctrl)state <= auto_refresh ;elsestate <= self_refresh ;end
else if( cmd == 4'b0000 )state <= load_mode_register ;reg [7:0]state_cnt ;
always@(posedge clk or negedge rst_n)
if(!rst_n)beginstate_cnt <= 0 ;CKE <= 1 ;CS_N <= 1 ;RAS_N <= 1 ;CAS_N <= 1 ;WE_N <= 1 ;BA <= 0 ;SA <= 0 ;DQM <= 0 ;DQ_ctrl <= 1 ;//获取数据线的控制权DQ_out <= 0 ;end
else begincase(state)nop1 : begin CS_N <= 1 ; endnop2 : begin CS_N <= 0 ; RAS_N <= 1 ; CAS_N <= 1 ; WE_N <= 1 ; DQ_out <= write_data ;endactive: begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 1 ; WE_N <= 1 ; SA <= addr ; BA <= bank ;end read : begin CS_N <= 0 ; RAS_N <= 1 ; CAS_N <= 0 ; WE_N <= 1 ; SA <= addr ; BA <= bank ; DQM <= dqm_ctrl ; DQ_ctrl <= 0 ; endwrite : begin CS_N <= 0 ; RAS_N <= 1 ; CAS_N <= 0 ; WE_N <= 0 ; SA <= addr ; BA <= bank ; DQM <= dqm_ctrl ; DQ_out <= write_data ;endprecharge : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 1 ; WE_N <= 0 ; SA[10] <= addr[10] ; BA <= bank ;DQ_ctrl <= 1 ; end//sa[10] = 1 :对所有bank预充电 ; sa[10] = 0 : 对ba1 ba0 选中的bank预充电auto_refresh : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 0 ; WE_N <= 1 ; CKE <= 1 ; endself_refresh : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 0 ; WE_N <= 1 ; CKE <= 0 ; endload_mode_register : begin CS_N <= 0 ; RAS_N <= 0 ; CAS_N <= 0 ; WE_N <= 0 ; SA <= { 1'b0 , mode } ; enddefault:;endcaseendendmodule
`timescale 1ns/1ns
module sdram_ctrl_tb();reg fpga_clk ;
reg rst_n ;
reg write_sig ;
reg read_sig ;
reg [12:0]write_addr ;
reg [1:0] write_bank ;
reg [15:0]write_data ;
reg [12:0]read_addr ;
reg [1:0] read_bank ; wire sclk ;
wire CKE ;
wire CS_N ;
wire RAS_N ;
wire CAS_N ;
wire WE_N ;
wire [1:0]DQM ;//高电平时屏蔽
wire [12:0]SA ;//A12 - A0
wire [1:0]BA ;
wire [15:0]DQ;
wire [15:0]read_data;
wire trans_done;
wire [3:0]cmd_state ;
sdram_ctrl sdram_ctrl_inst(.fpga_clk(fpga_clk) ,.rst_n(rst_n) ,.write_sig(write_sig) ,.read_sig(read_sig) ,.write_addr(write_addr) ,.write_bank(write_bank) ,.write_data(write_data) ,.read_addr(read_addr) ,.read_bank(read_bank) , .trans_done(trans_done) ,.read_data(read_data) ,.sclk(sclk) ,.CKE(CKE) ,.CS_N(CS_N) ,.RAS_N(RAS_N) ,.CAS_N(CAS_N) ,.WE_N(WE_N) ,.DQM(DQM) ,.SA(SA) ,.BA(BA) ,.DQ(DQ)
);mt48lc16m16a2 mt48lc16m16a2_inst(.Dq(DQ),.Addr(SA),.Ba(BA),.Clk(sclk),.Cke(CKE),.Cs_n(CS_N),.Ras_n(RAS_N),.Cas_n(CAS_N),.We_n(WE_N),.Dqm(DQM)
);pulldown(DQ[15]);
pulldown(DQ[14]);
pulldown(DQ[13]);
pulldown(DQ[12]);
pulldown(DQ[11]);
pulldown(DQ[10]);
pulldown(DQ[9]);
pulldown(DQ[8]);
pulldown(DQ[7]);
pulldown(DQ[6]);
pulldown(DQ[5]);
pulldown(DQ[4]);
pulldown(DQ[3]);
pulldown(DQ[2]);
pulldown(DQ[1]);
pulldown(DQ[0]);
assign cmd_state = {CS_N,RAS_N,CAS_N,WE_N} ;initial fpga_clk = 0 ;
always #10 fpga_clk = !fpga_clk ;
initial beginrst_n = 0 ;write_sig = 0 ;read_sig = 0 ;write_addr = 0 ;write_bank = 0 ;write_data = 0 ;read_addr = 0 ;read_bank = 0 ;#201 ;rst_n = 1 ;#102000;#200 ;write_addr = 13'd2 ;write_bank = 2'd1;write_data = 16'h5a5a ;write_sig = 1;#70;write_data = 16'h5a5b ;#10;write_data = 16'h5a5c ;#10;write_data = 16'h5a5d ;#200 ;write_sig = 0;#5000;read_addr = 13'd2 ;read_bank = 2'd1;read_sig = 1 ;#200 ;read_sig = 0 ;#10000;$stop ;endendmodule
3.仿真
1.上点初始化
2.写数据(带自动预充电)
3.读数据(带自动预充电)
读出来的数据,DQ的最后一个数据只有7.6ns,不知道是什么原因。
但是移相适当仍然可以读取。
接下来对AC609板载的SDRAM:w9812g6kh进行设计,并进行板级验证。
三、型号w9812g6kh的sdram
通过查看w9812g6kh芯片的器件手册,发现它的读/写/充电/等命令设置均与MT48LC16M16A2的规则相同,只是这两个芯片容量不一样,w9812g6kh为128M,只有12个地址引脚,而MT48LC16M16A2为256M,有13个地址引脚。所以程序上只需要修改地址引脚即可。
为了上板验证程序的可行性,仿照IIC协议的测试方法,用uart-sdram联合测试,通过上位机发送读写数据来控制FPGA对w9812g6kh进行读写,此处仍需要建立通信帧,规则与IIC协议笔记差不多,如下:
//***************** ******************//
// 串口波特率:115200 //
// 通信帧格式: //
// AA AA HA LA RW DA DA 55 //
// 其中,AA AA 为帧头;55为帧尾; //
// HA、LA为存储器地址 //
// RW为读写控制,读:5A ;写:A5 //
// DA为要写入的数据,读的时候可为任意值 //
// ********************************* //
sdram的控制程序设置为BL=1的模式,(使用其他BL只需修改对应的线性序列机和模式寄存器即可)
1.代码设计
//***************** ******************//
// 串口波特率:115200 //
// 通信帧格式: //
// AA AA HA LA RW DA DA 55 //
// 其中,AA AA 为帧头;55为帧尾; //
// HA、LA为存储器地址 //
// RW为读写控制,读:5A ;写:A5 //
// DA为要写入的数据,读的时候可为任意值 //
// ********************************* //module uart_sdram(input fpga_clk ,input rst_n ,input uart_rx ,output rx_done ,output uart_tx ,output sclk ,output CKE ,output CS_N ,output RAS_N ,output CAS_N ,output WE_N ,output [1:0]DQM ,//高电平时屏蔽output [11:0]SA ,//A12 - A0output [1:0]BA ,inout [15:0]DQ);//receive uart data
//wire rx_done ;
wire [7:0]rx_data ;
uart_receive uart_rec_inst(.clk(fpga_clk) ,.reset(rst_n) ,.baud_rate('d5) ,//115200.uart_rx(uart_rx), .data(rx_data) ,.rx_done(rx_done) );//Shift register
reg [7:0]rec_shift_reg[7:0] ;
reg rw_flag ;
wire trans_done ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)beginrec_shift_reg[0] <= 0 ;rec_shift_reg[1] <= 0 ;rec_shift_reg[2] <= 0 ;rec_shift_reg[3] <= 0 ;rec_shift_reg[4] <= 0 ;rec_shift_reg[5] <= 0 ;rec_shift_reg[6] <= 0 ;rec_shift_reg[7] <= 0 ;rw_flag <= 0 ;end
else if(rx_done)beginrec_shift_reg[0] <= rec_shift_reg[1] ;rec_shift_reg[1] <= rec_shift_reg[2] ;rec_shift_reg[2] <= rec_shift_reg[3] ; rec_shift_reg[3] <= rec_shift_reg[4] ; rec_shift_reg[4] <= rec_shift_reg[5] ; rec_shift_reg[5] <= rec_shift_reg[6] ; rec_shift_reg[6] <= rec_shift_reg[7] ; rec_shift_reg[7] <= rx_data ; rw_flag <= 1 ;end
else if(trans_done)rw_flag <= 0 ;reg [15:0]write_addr ;
reg [15:0]read_addr ;
reg [15:0]write_data ;
reg [15:0]read_data ;
wire [15:0]rd_data ;
reg write_pulse ;
reg read_pulse ;sdram_ctrl sdram_ctrl_inst(.fpga_clk(fpga_clk) ,.rst_n(rst_n) ,.write_sig(write_pulse) ,.read_sig(read_pulse) ,.write_addr(write_addr[11:0]) ,.write_bank(write_addr[15:14]) ,.write_data(write_data) ,.read_addr(read_addr[11:0]) ,.read_bank(read_addr[15:14]) , .trans_done(trans_done) ,.read_data(rd_data) ,.sclk(sclk) ,.CKE(CKE) ,.CS_N(CS_N) ,.RAS_N(RAS_N) ,.CAS_N(CAS_N) ,.WE_N(WE_N) ,.DQM(DQM) ,//高电平时屏蔽.SA(SA) ,//A12 - A0.BA(BA) ,.DQ(DQ)
);wire uart_send_done ;
reg uart_send_en ;
uart_send uart_send( .clk(fpga_clk),.reset(rst_n),.data(read_data[7:0]),.send_en(uart_send_en),.baud_rate(5),//115200.uart_tx(uart_tx),.tx_done(uart_send_done)
);//Parsing frames
localparam frames_header = 8'hAA ;
localparam frames_tail = 8'h55 ;
localparam read_option = 8'h5A ;
localparam write_option = 8'hA5 ;
reg [15:0]wr_cnt ;
reg [15:0]rd_cnt ;
always@(posedge fpga_clk or negedge rst_n)
if(!rst_n)beginwrite_addr <= 0 ;read_addr <= 0 ;write_data <= 0;read_data <= 0 ;write_pulse <= 0 ;read_pulse <= 0 ;wr_cnt <= 0 ;rd_cnt <= 0 ;endelse if( rw_flag )beginif ( (rec_shift_reg[0] == frames_header) && (rec_shift_reg[1] == frames_header) && (rec_shift_reg[7] == frames_tail) )beginif(rec_shift_reg[4] == write_option )beginwrite_addr <= { rec_shift_reg[2] , rec_shift_reg[3] } ;write_data <= {rec_shift_reg[5],rec_shift_reg[6]} ;wr_cnt <= wr_cnt + 1 ;//write signalif( wr_cnt < 3 )write_pulse <= 1 ;else if(trans_done)beginwr_cnt <= 0 ;end elsewrite_pulse <= 0 ; endelse if ( rec_shift_reg[4] == read_option )beginread_addr <= { rec_shift_reg[2] , rec_shift_reg[3] } ;//read signalrd_cnt <= rd_cnt + 1 ;if(trans_done)beginread_data <= rd_data ;read_pulse <= 0 ;rd_cnt <= 0 ;endelse if(rd_cnt <3)read_pulse <= 1 ;elseread_pulse <= 0 ;endendend
elsebeginwrite_pulse <= 0 ;read_pulse <= 0 ;wr_cnt <= 0 ;rd_cnt <= 0 ;endalways@(posedge fpga_clk or negedge rst_n)
if(!rst_n)uart_send_en <= 0 ;
else if(trans_done && (rec_shift_reg[4] == read_option) )uart_send_en <= 1 ;
else if(uart_send_done)uart_send_en <= 0 ;endmodule
2.板级验证
fpga向sdram芯片写入数据16‘h1234,并返回低位8’h34。
相关文章:

SDRAM学习笔记(MT48LC16M16A2,w9812g6kh)
一、基本知识 SDRAM : 即同步动态随机存储器(Synchronous Dynamic Random Access Memory), 同步是指其时钟频率与对应控制器(CPU/FPGA)的系统时钟频率相同,并且内部命令 的发送与数据传输都是以该时钟为基准ÿ…...

ARM 学习笔记3 STM32G4 定时器相关资料整理
官方文档 AN4539 HRTIM cookbookAN4539_HRTIM使用指南 中文版的文档,注意文档的版本号滞后于英文原版ST MCU中文文档 中文文档汇总 博客文章 STM32-定时器详解【STM32H7教程】第63章 STM32H7的高分辨率定时器HRTIM基础知识和HAL库APIstm32f334 HRTIM触发ADC注入中…...

LeetCode 917 仅仅反转字母 简单
题目 - 点击直达 1. XXXXX1. 917 仅仅反转字母 简单1. 原题链接2. 题目要求3. 基础框架 2. 解题思路1. 思路分析2. 时间复杂度3. 代码实现 1. XXXXX 1. 917 仅仅反转字母 简单 给你一个字符串 s ,根据下述规则反转字符串: 所有非英文字母保留在原有位置…...

JAVA深化篇_25—— IO流章节全网最全总结(附详细思维导图)
IO流章节全网最全总结(附详细思维导图) 本篇开始,先奉上思维导图:(下载下来为超高清图,不愁小伙伴看不清!) 按流的方向分类: 输入流:数据源到程序(InputStr…...

易基因:ChIP-seq等揭示BRWD3调控KDM5活性以维持H3K4甲基化水平的表观机制|PNAS
大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 组蛋白修饰对调控染色质结构和基因表达至关重要,组蛋白修饰失调可能导致疾病状态和癌症。染色质结合蛋白BRWD3(Bromodomain and WD repeat-containing protein 3&…...

C++深度优先(DFS)算法的应用:收集所有金币可获得的最大积分
涉及知识点 深度优化(DFS) 记忆化 题目 节点 0 处现有一棵由 n 个节点组成的无向树,节点编号从 0 到 n - 1 。给你一个长度为 n - 1 的二维 整数 数组 edges ,其中 edges[i] [ai, bi] 表示在树上的节点 ai 和 bi 之间存在一条边。另给你一个下标从 0…...

uniapp中APP端使用echarts用formatter设置y轴保留2位小数点不生效
uniapp使用echarts,在内置浏览器中,设置保留2位小数能正常显示(代码如下),但是在APP端这个设置不起作用。 yAxis: {type: value,axisLabel: {formatter: function (val) {return val.toFixed(2); //y轴始终保留小数点…...

无糖茶饮三十年,从无人问津到人手一瓶
【潮汐商业评论/原创】 Joan又在外卖上点了一堆瓶装茶饮,东方树叶、燃茶、三得利乌龙茶……买了四五种纯茶,用她的话说,和美式咖啡相比,这些无糖茶更适合他这个中国体质。 事实上,越来越多的消费者开始像Joan一样&am…...

面向Three.js开发者的3D自动纹理化开发包
DreamTexture.js 是面向 three.js 开发者的 3D 模型纹理自动生成与设置开发包,可以为 webGL 应用增加 3D 模型的快速自动纹理化能力。 图一为原始模型, 图二图三为贴图后的模型。提示词: city, Realistic , cinematic , Front view ,Game scene graph 1、…...

数字孪生技术与VR:创造数字未来
在当今数字化浪潮中,数字孪生和虚拟现实(VR)技术是两大亮点,它们以独特的方式相互结合,为各个领域带来了创新和无限可能。本篇文章将探讨数字孪生与VR之间的关系,以及它们如何共同开辟未来的新前景。 数字…...

系统架构设计师-第15章-面向服务架构设计理论与实践-软考学习笔记
面向服务的体系结构(Service-Oriented Architecture, SOA) 面向服务的体系结构(Service-Oriented Architecture, SOA)是一种软件架构模式,它将应用程序的不同功能组织为一组可重用的、松耦合的、自治的服务,这些服务通…...

为什么我觉得Rust比C++复杂得多?
为什么我觉得Rust比C复杂得多? Rust自学确实有一定门槛,很多具体问题解决起来搜索引擎也不太帮的上忙,会出现卡住的情况,卡的时间长了就放弃了。最近很多小伙伴找我,说想要一些c语言资料,然后我根据自己从…...

python sqlalchemy(ORM)- 03 增删改查
文章目录 ORM更新数据ORM查询ORM删除操作处理关系对象多表的关联查询 本节所有案例基于(第一节 python sqlalchemy(ORM)- 01 ORM简单使用)中的User、Address两个模型类 ORM更新数据 查询到模型类对象,直接修改其属性…...

Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(上)
Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart语言吉祥物Dash(上) 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://…...

学习gorm:彻底弄懂Find、Take、First和Last函数的区别
在gorm中,要想从数据库中查找数据有多种方法,可以通过Find、Take和First来查找。但它们之间又有一些不同。本文就详细介绍下他们之间的不同。 一、准备工作 首先我们有一个m_tests表,其中id字段是自增的主键,同时该表里有3条数据…...

796. 子矩阵的和(二维前缀和)
题目: 796. 子矩阵的和 - AcWing题库 思路: 1.暴力搜索(搜索时间复杂度为O(n2),很多时候会超时) 2. 前缀和(左上角(二维)前缀和):本题特殊在不是直接求前…...

利用ChatGPT进行股票走势分析
文章目录 1. 股票分析2. 技巧分析3. 分析技巧21. 股票分析 这张图片显示了一个股票交易软件的界面。以下是根据图片内容的一些解读: 股票代码: 图片右上角显示的代码是“600517”,这是股票的代码。 图形解读: 该图展示了股票的日K线图。其中,蜡烛图表示每日的开盘、收盘、最…...

万字解析设计模式之单例模式
一、概述 1.1简介 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保…...

vue2.x 二次封装element ui 中的el-dialog
在做后台管理系统的时候,dialog组件是我们使用频率比较高的组件,但是有一些需求现有的组件是不满足的。因此会需要我们做二次封装。 组件本身的属性我们保留,只需要根据需求添加,然后在使用的时候props去拿取使用就可以了。 本次遇…...

ssh连接Ubuntu虚拟机出现connection reset by ip地址 port 22怎么解决
使用前提:我是用Windows去连接安装在本机的Ubuntu虚拟机的时候出现的这个问题。 解决的方法:我使用了很多网络上方法,都没有用,发现我把IP地址搞错了 请继续看下去,因为有可能你会错过解决的方法。 在Windows网络连…...

树莓派4B安装ffmpeg
环境: piraspberrypi:~/x264 $ lsb_release -aNo LSB modules are available.Distributor ID: RaspbianDescription: Raspbian GNU/Linux 10 (buster)Release: 10Codename: buster 装H264 git clone --depth 1 https://code.videolan.org/video…...

LeetCode|动态规划|1035. 不相交的线 、53. 最大子数组和
目录 一、1035. 不相交的线 1.题目描述 2.解题思路 3.代码实现 二、53. 最大子数组和 1.题目描述 2.解题思路 3.代码实现(动态规划解法) 一、1035. 不相交的线 1.题目描述 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现…...

一体式IO模块:汽车行业的数字化转型助推器
随着市场经济需求的不断增长,汽车行业的自动化和智能化已经成为行业发展的必然趋势。在这个背景下,汽车行业的工作流程变得越来越复杂,工业机器人的广泛应用为汽车生产提供了强有力的支持,它们扮演着装配工、操作工、焊接工等多种…...

OpenCV官方教程中文版 —— Hough 直线变换
OpenCV官方教程中文版 —— Hough 直线变换 前言一、原理二、OpenCV 中的霍夫变换三、Probabilistic Hough Transform 前言 目标 • 理解霍夫变换的概念 • 学习如何在一张图片中检测直线 • 学习函数:cv2.HoughLines(),cv2.HoughLinesP() 一、原理…...

【Axure高保真原型】百分比堆叠柱状图
今天和大家分享百分比堆叠柱状图的的原型模板,鼠标移入堆叠柱状图后,会显示数据弹窗,里面可以查看具体项目对应的数据和占比。那这个原型模板是用中继器制作的,所以使用也很方便,只需要在中继器表格里维护项目数据信息…...

Vue.js中的双向数据绑定(two-way data binding)
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

TFN 2.5G SDH传输分析仪 FT100-D300S
今天给大家带来一款TFN 2.5G SDH传输分析仪--TFN FT100-D300S. D300S SDH测试模块,是FT100智能网络测试平台产品家族的一部分,是一个坚固耐用、锂电池超长供电的传统PDH/SDH测试解决方案,支持2.5Gbps到2.048Mbps速率的传输链路测试。支持在线…...

电脑录像功能在哪?一文帮你轻松破解
“电脑录像功能在哪里呀?最近因工作上的原因,需要使用电脑来录像,但是找了一上午都找不到在哪里,眼看已经快没时间了,现在真的很急,希望大家帮帮我。” 电脑已经成为了人们生活和工作中必不可少的工具&…...

基于长短期神经网络的可上调容量PUP预测,基于长短期神经网络的可下调容量PDO预测,LSTM可调容量预测
目录 背影 摘要 代码和数据下载:基于长短期神经网络的可上调容量PUP预测,基于长短期神经网络的可下调容量PDO预测,LSTM可调容量预测(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88230834 LSTM的基本定义 LSTM实现的步骤 基于长短…...

站群服务器有哪些优势?
站群服务器有哪些优势? 站群服务器是单独为一个网站或者多个网站配置独立IP的一种服务器。企业或是用户如果想组建多个网站的话就需要用站群服务器了。 站群服务器可以提高搜索引擎多个网站的关注度,提高网站文章的收录以及网站文章的访问量。站群服务器有哪些优势…...