AHB总线下的slave ram的verilog代码
- 格式:pdf
- 大小:35.35 KB
- 文档页数:5
verilog mem用法-回复Verilog Mem 用法Verilog 是一种硬件描述语言(HDL),主要用于硬件设计和验证。
在硬件设计中,内存(Memory)是一种非常重要且常用的元件。
在Verilog 中,可以使用mem 来定义和操作内存。
本文将一步一步回答关于Verilog Mem 的用法,并详细介绍使用mem 的步骤和注意事项。
第一步:定义内存的大小和宽度在Verilog 中,可以使用mem 属性来定义内存的大小和宽度。
内存的大小是指存储单元的数量,宽度是指每个存储单元的位数。
例如,要定义一个大小为64,并且每个存储单元宽度为8 位的内存,可以使用下面的代码:reg [7:0] mem [0:63];这个代码定义了一个名为mem 的内存,大小为64,每个存储单元宽度为8 位。
关键字reg 表示这是一个寄存器,[7:0] 表示每个存储单元的宽度为8 位,[0:63] 表示总共有64 个存储单元。
第二步:向内存写入数据内存的另一个常见操作是向内存中写入数据。
在Verilog 中,可以使用内存的索引和赋值操作符来写入数据。
例如,要向内存的第10 个存储单元写入数据01100101,可以使用下面的代码:mem[10] = 8'b01100101;这个代码将8 位的数据01100101 赋值给内存的第10 个存储单元。
8'b 表示这是一个8 位的二进制数。
第三步:从内存中读取数据除了写入数据,从内存中读取数据也是很常见的操作。
在Verilog 中,可以通过内存的索引来读取数据。
例如,要从内存的第20 个存储单元读取数据,并将其存储在一个变量中,可以使用下面的代码:reg [7:0] data;data = mem[20];这个代码将内存的第20 个存储单元的值赋值给变量data。
注意,变量data 的宽度必须和内存的存储单元宽度一致,否则会导致数据截断或溢出的问题。
第四步:使用内存进行操作内存不仅仅可以用于存储数据,还可以用于进行其他操作,例如加法、减法等。
V e r i l o g H D L代码_A H B总线_m a s t e r部分------------------------------------------作者xxxx------------------------------------------日期xxxxmodule ahb_master(HBUSREQ,HLOCK,HTRANS,HADDR,HWRITE,HSIZE,HBURST,HWDATA,HS EL,hcount,HRESETn,HCLK,HGRANT,HREADY,HRESP,HRDATA,BUSREQ,AD DREQ,WRITE,ADDR,SIZE,BURST,SEL,TRANS,WDATA);output HBUSREQ,HLOCK,HWRITE;output [1:0]HTRANS,HSEL;output [31:0]HADDR,HWDATA;output [2:0]HSIZE,HBURST;input HGRANT,HREADY,HCLK,HRESETn,BUSREQ,ADDREQ,WRITE;input [31:0]ADDE,WDATA;input [2:0]SIZE,BURST;input [1:0]HRESP,SEL,TRANS;input [31:0]HRDATA;reg HBUSRREQ,HLOCK,HWRITE,hcount;reg [1:0]HTRANS,HSEL;reg [31:0]HADDR,HWDATA;reg [2:0]HSIZE,HBURST;wire HGRANT,HREADY,HCLK,HRESETn,WRITE;wire [31:0]ADDR,WDATA;wire [2:0]SIZE,BURST;wire [1:0]HRESP,SEL,TRANS;wire [31:0]HRDATA;reg bus_reg,adde_reg,new_hready,old_hready;reg [31:0]RDATA;reg [31:0]h_addr;parameter OKAY=2'b00ERROR=2'b01RETRY=2'b10SPLIT=2'b11;always @(posedge HCLK)beginif(!HRESETn)beginHBUSREQ=0;HLOCK=0;HWRITE=0;HTRANS=2'b00;HSEL=2'b00;HADDR=32'h000000000; HWDATA=32'h000000000; HSIZE=2'b00;HBURST=2'b00;bus_reg=0;addr_reg=0;new_hready=0;old_hready=0;hcount=0;endendalways @(posedge HCLK) beginif(HRESETn)beginif(!addr_reg)beginif(ADDREQ)beginHADDR=ADDR;h_addr=ADDR;HWRITE=WRITE;HSIZE=SIZE;HBURST=BURST;HSEL=SEL;HTRANS=TRANS;addr_reg=1'b1;HWDATA=32'h000000000; endendelse if(addr_reg)beginHADDR=32'h000000000; HWRITE=1'b0;HSIZE=3'b000;HBURST=3'b000;HTRANS=2'b00;addr_reg=1'b0;endif(!ADDREQ)beginif(WRITE)beginhcount=0;case({TRANS})2'b00:beginHWDATA=WDATA;if(HREADY && !new_hready && HRESP==ERROR) new_hready=1;else if(new_hready!=old_hready)HWDATA=32'h00000000;end2'b01:beginhcount=hcount+1;new_hready=0;HWDATA=WDATA;if(HREADY &&!new_hready && HRESP)new_hready=1;else if(new_hready!=old hready)hWDATA=32'h00000000;end2'b10:beginHWDATA=32'h00000000;end2'b11:beginhcount=hcount+1;HWDATA=WDATA;if(HREADY && HRESP==OKAY)beginif(!new_hready)new_hready=1;endelse if(new_hready!=old_hready)beginHWDATA=WDATA;new_hready=0;endelse if(HREADY && HRESP==ERROR)beginHWDATA=32'h00000000;endendendcaseendelse if(!WRITE)begincase({TRANS})2'b00:beginif(!HREADY)RDATA=HRDATA;else if(HREADY)RDATA=32'h00000000; end2'b01:beginif(!HREADY)beginRDATA=HRDATA;if(HBURST==000)h_addr=h_addr+1;elseh_addr=h_addr-1;endelse if(HREADY)RDATA=32'h00000000; end2'b10:beginRDATA=32'h00000000; end2'b11:beginif(!HREADY)beginRDATA=HRDATA;if(HBURST==000)h_addr=h_addr+1;elseh_addr=h_addr-1;endendcaseendendendendmodulemodule ram_top(HCLK ,HRESETn ,HSEL_s ,HADDR_s ,HBURST_s ,HTRANS_s ,HRDATA_s ,HWDATA_s ,HWRITE_s ,HREADY_s ,HRESP_s);input HCLK ;input HRESETn ;input HSEL_s ;input [19:0] HADDR_s ;input [2:0] HBURST_s ;input [1:0] HTRANS_s ;input [31:0] HWDATA_s ; input HWRITE_s ;output [1:0] HRESP_s ;output [31:0] HRDATA_s ; output HREADY_s ;wire [31:0] ram_RDATA ;wire [17:0] ram_ADDR ;wire [31:0] ram_WDATA ; wire ram_WRITE ;ram_ahbif U_ram_ahbif (.HCLK (HCLK ),.HRESETn (HRESETn ),.HSEL_s (HSEL_s ),.HADDR_s (HADDR_s ),.HBURST_s (HBURST_s ),.HTRANS_s (HTRANS_s ),.HRDATA_s (HRDATA_s ),.HWDATA_s (HWDATA_s ), .HWRITE_s (HWRITE_s ),.HREADY_s (HREADY_s ),.HRESP_s (HRESP_s ),.ram_RDATA (ram_RDATA ), .ram_ADDR (ram_ADDR ),.ram_WDATA (ram_WDATA ), .ram_WRITE (ram_WRITE ) );ram_infer U_ram_infer(.q (ram_RDATA ),.a (ram_ADDR ),.d (ram_WDATA ),.we (ram_WRITE ),.clk (HCLK ));endmodulemodule ram_infer(q ,a ,d ,we ,clk);output [31:0] q ;input [31:0] d ;input [17:0] a ;input we ;input clk ;reg [31:0] mem [262143:0] ; always @(posedge clk) beginif (we)beginmem[a] <= d;endendassign q = mem[a]; endmodulemodule ram_ahbif(HCLK ,HRESETn ,HSEL_s ,HADDR_s ,HBURST_s ,HTRANS_s ,HRDATA_s ,HWDATA_s ,HWRITE_s ,HREADY_s ,HRESP_s ,ram_RDATA ,ram_ADDR ,ram_WDATA ,ram_WRITE);/////////////////////////////////////////declaration of input & output///////////////////////////////////////input HCLK ;input HRESETn ;input HSEL_s ;input [19:0] HADDR_s ;input [2:0] HBURST_s ;input [1:0] HTRANS_s ;input [31:0] HWDATA_s ;input HWRITE_s ;output [1:0] HRESP_s ;output [31:0] HRDATA_s ;output HREADY_s ;input [31:0] ram_RDATA ;output [17:0] ram_ADDR ;output [31:0] ram_WDATA ;output ram_WRITE ;/////////////////////////////////////////declaration of registers & wires/////////////////////////////////////// wire [1:0] HRESP_s ;wire [31:0] HRDATA_s ;reg HREADY_s ;wire [31:0] ram_WDATA ;reg [17:0] ram_ADDR ;reg ram_WRITE ;wire wr_en ;wire rd_en ;wire ready_en ;/////////////////////////////////////////program & function///////////////////////////////////////assign HRESP_s = 2'b00;always@(posedge HCLK or negedge HRESETn)begin //HSIZE = 3'b010--32bitsif(!HRESETn) beginram_ADDR <= 18'b000000000000000000;endelse if (HSEL_s == 1'b1)beginram_ADDR <= HADDR_s[19:2];endendassign wr_en = HSEL_s & HTRANS_s[1] & HWRITE_s; always@(posedge HCLK or negedge HRESETn)beginif(!HRESETn)beginram_WRITE <= 1'b0;endelse if(wr_en)beginram_WRITE <= 1'b1;endelsebeginram_WRITE <= 1'b0;endendassign ram_WDATA= HWDATA_s;assign HRDATA_s = ram_RDATA;assign ready_en = HSEL_s & HTRANS_s[1]; always@(posedge HCLK or negedge HRESETn) beginif(!HRESETn)beginHREADY_s <= 1'b0;endelse if(ready_en)beginHREADY_s <= 1'b1;endelsebeginHREADY_s <= 1'b0;endendendmodule。
一、工程建立规范:1、工程的组成:(1)一个顶层文件夹(2)顶层文件夹下,至少包括以下四个子文件夹a)project文件夹:存放ISE工程文件,包括ise、bit、mac等文件b)source文件夹:存放verilog源文件c)explain文件件:存放注释说明文档d)test文件夹:存放测试程序代码,可进一步分为软件调试程序、硬件调试程序2、工程的命令:(3)定层文件夹命令为top_xxx,xxx为工程的识别名称(4)顶层文件夹的子文件夹分别命名为:project、source、explain、test二、RTL CODE 规范1.标准的文件头在每一个版块的开头一定要使用统一的文件头,其中包括作者名,模块名,创建日期,概要,更改记录,版权等必要信息。
统一使用以下的文件头:// **************************************************************// COPYRIGHT(c)2005, Hislicon Technologies Co, Ltd// All rights reserved.//// IP LIB INDEX : IP lib index just sa UTOPIA_B// IP Name : the top module_name of this ip, usually, is same// as the small ip classified name just as UTOPIA// File name : file_name of the file just as “tx_fifo.v”// Module name : module_name of this file just as “TX_FIFO”// Full name : complete Emglish nme of this abbreviated//// Author : Athor/ID// Email : Author‟s email// Data :// Version : V 1.0////Abstract :// Called by : Father Module//// Modification history// ------------------------------------------------------------------------------------------------------// //// $Log$//// *********************************************************************2. 标准的module 格式(module 整体结构)对于模块的书写采用统一的格式便于项目内部成员的理解和维护,我们用批处理建立了一个MODULE模块,其内容解释如下:●端口定义按照输入,输出,双向的顺序:●模块名、模块例化名统一,例化名前加大写U_以区分(多次例化另加标识),三者关系:文件名:xxx .v (小写)模块名:Xxx (首字母大写)例化名:U1_xxx (首字母大写)IP 内部所有的模块名都要加IP名或者IP名简称作前缀,如USB_CTRL、USB_TX_FIFO。
双口RAM的verilog描述
双口RAM的verilog描述
分类:数字电路
* RAM的verilog描述如下:
module ram(din,ain,dout,aout,rd,wr);//这是一个双口RAM,分别有:
//输入端:输入地址ain;输入数据din;上升沿有效的写信号wr;
//输出端:输出地址aout;输出数据dout;高电平有效的读信号rd;
inout [7:0] din;
input [7:0] ain,aout;
input rd,wr;
output [7:0] dout;
reg [7:0] memory [0:255]; //请注意这是存储阵列的描述方法,描述了一个共有2 56个字的存储阵列,
//每个字是8位
assign dout = rd ? memory[aout] : 8'bz; //"assign"关键字表示并行赋值语句的
开始
//"?"运算符的作用和在C语言中一样
//"?"运算符的作用和在C语言中一样
//"8'bz"是一个常量,表示一个字节的高阻态,其中
//8表示长度是8bit,"'"是固定分割符,"b"表示后面的数据是以比特形式给出的, //"z"表示高阻;
//举例:4'ha表示长4bit的数"1010"
//类似的还可举出5'b10111,6'o33等等
always @(posedge wr)
memory[ain] = din;
endmodule。
Verilog语句讲解一、Verilog语言简介1.1 什么是Verilog语言Verilog是一种硬件描述语言(HDL),用于描述数字电路和系统的行为和结构。
它是一种高级语言,可以用于设计和验证各种电子系统,从简单的门电路到复杂的处理器和系统芯片。
1.2 Verilog语言的特点•面向事件的建模:Verilog可以描述数字电路中的事件和信号变化,使得设计者可以更好地理解和建模系统的行为。
•层次化建模:Verilog允许设计者使用模块化的方式组织代码,从而实现对复杂系统的分层描述。
•并发性支持:Verilog支持并发执行,可以同时执行多个操作,从而提高了系统的性能和效率。
•灵活性:Verilog可以描述各种类型的电路和系统,包括数字逻辑电路、时序电路、存储器和通信接口等。
二、Verilog语句的基本结构2.1 模块定义语句在Verilog中,一个模块是由输入、输出和内部逻辑组成的。
模块定义语句用于定义一个模块的接口和行为。
module module_name(input_list, output_list);// 内部逻辑endmodule•module_name:模块的名称,用于在其他模块中引用该模块。
•input_list:输入端口列表,用于定义模块的输入信号。
•output_list:输出端口列表,用于定义模块的输出信号。
2.2 信号定义语句Verilog中使用信号来表示数据和控制信号。
信号定义语句用于定义信号的类型和宽度。
reg [width-1:0] signal_name;•reg:表示信号的类型为寄存器,可以存储数据。
•[width-1:0]:表示信号的位宽,从高位到低位。
•signal_name:信号的名称,用于在模块内部引用该信号。
2.3 时钟信号定义语句在时序电路中,时钟信号是非常重要的。
Verilog中使用时钟信号来同步和控制电路的操作。
input wire clk;•input wire:表示时钟信号是一个输入信号。
module sdr_test(clk,rst_n,sdram_clk,sdram_cke,sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n,sdram_ba,sdram_addr,sdram_data,//sdram_udqm,sdram_ldqmrs232_tx,/* sdram_rd_req,sdram_wr_ack,sdram_rd_ack,sys_data_out,sdram_busy,sys_data_in,sys_dout_rdy,*/ rdf_dout/*,rdf_rdreq*/);input clk; //系统时钟,100MHzinput rst_n; //复位信号,低电平有效// FPGA与SDRAM硬件接口output sdram_clk; // SDRAM时钟信号output sdram_cke; // SDRAM时钟有效信号output sdram_cs_n; // SDRAM片选信号output sdram_ras_n; // SDRAM行地址选通脉冲output sdram_cas_n; // SDRAM列地址选通脉冲output sdram_we_n; // SDRAM写允许位output[1:0] sdram_ba; // SDRAM的L-Bank地址线output[11:0] sdram_addr; // SDRAM地址总线//output sdram_udqm; // SDRAM高字节屏蔽//output sdram_ldqm; // SDRAM低字节屏蔽inout[15:0] sdram_data; // SDRAM数据总线output rs232_tx; //RS232发送数据信号////////////////////////////////////////////////// SDRAM的封装接口测试引出/*output sdram_rd_req; //系统读SDRAM请求信号output sdram_wr_ack; //系统写SDRAM响应信号output sdram_rd_ack; //系统读SDRAM响应信号output[15:0] sys_data_in; //写SDRAM时数据暂存器,4个突发读写字数据,默认为00地址bit15-0;01地址bit31-16;10地址bit47-32;11地址bit63-48output[15:0] sys_data_out; //读SDRAM时数据暂存器,(格式同上)output sdram_busy; // SDRAM忙标志,高表示SDRAM处于工作中output sys_dout_rdy; // SDRAM数据输出完成标志*/output[15:0] rdf_dout; //sdram数据读出缓存FIFO输出数据总线//output rdf_rdreq; //sdram数据读出缓存FIFO数据输出请求,高有效////////////////////////////////////////////////// SDRAM的封装接口wire sdram_wr_req; //系统写SDRAM请求信号wire sdram_rd_req; //系统读SDRAM请求信号wire sdram_wr_ack; //系统写SDRAM响应信号,作为wrFIFO的输出有效信号wire sdram_rd_ack; //系统读SDRAM响应信号,作为rdFIFO的输写有效信号wire[21:0] sys_addr; //读写SDRAM时地址暂存器,(bit21-20)L-Bank地址:(bit19-8)为行地址,(bit7-0)为列地址wire[15:0] sys_data_in; //写SDRAM时数据暂存器wire[15:0] sys_data_out; //sdram数据读出缓存FIFO输入数据总线wire sdram_busy; // SDRAM忙标志,高表示SDRAM处于工作中wire sys_dout_rdy; // SDRAM数据输出完成标志//wrFIFO输入控制接口wire[15:0] wrf_din; //sdram数据写入缓存FIFO输入数据总线wire wrf_wrreq; //sdram数据写入缓存FIFO数据输入请求,高有效//rdFIFO输出控制接口wire[15:0] rdf_dout; //sdram数据读出缓存FIFO输出数据总线wire rdf_rdreq; //sdram数据读出缓存FIFO数据输出请求,高有效//系统控制相关信号接口wire clk_25m; //PLL输出25MHz时钟wire clk_100m; //PLL输出100MHz时钟wire sys_rst_n; //系统复位信号,低有效//------------------------------------------------//例化系统复位信号和PLL控制模块sys_ctrl uut_sysctrl(.clk(clk),.rst_n(rst_n),.sys_rst_n(sys_rst_n),.clk_25m(clk_25m),.clk_100m(clk_100m),.sdram_clk(sdram_clk));//------------------------------------------------//例化SDRAM封装控制模块sdram_top uut_sdramtop( // SDRAM.clk(clk_100m),.rst_n(sys_rst_n),.sdram_wr_req(sdram_wr_req),.sdram_rd_req(sdram_rd_req),.sdram_wr_ack(sdram_wr_ack),.sdram_rd_ack(sdram_rd_ack),.sys_addr(sys_addr),.sys_data_in(sys_data_in),.sys_data_out(sys_data_out),.sys_dout_rdy(sys_dout_rdy),//.sdram_clk(sdram_clk),.sdram_busy(sdram_busy),.sdram_cke(sdram_cke),.sdram_cs_n(sdram_cs_n),.sdram_ras_n(sdram_ras_n),.sdram_cas_n(sdram_cas_n),.sdram_we_n(sdram_we_n),.sdram_ba(sdram_ba),.sdram_addr(sdram_addr),.sdram_data(sdram_data)// .sdram_udqm(sdram_udqm),// .sdram_ldqm(sdram_ldqm));//------------------------------------------------//读写SDRAM数据缓存FIFO模块例化sdfifo_ctrl uut_sdffifoctrl(.clk_25m(clk_25m),.clk_100m(clk_100m),.wrf_din(wrf_din),.wrf_wrreq(wrf_wrreq),.sdram_wr_ack(sdram_wr_ack),//.sys_addr(sys_addr),.sys_data_in(sys_data_in),.sdram_wr_req(sdram_wr_req),.sys_data_out(sys_data_out),.rdf_rdreq(rdf_rdreq),.sdram_rd_ack(sdram_rd_ack),.rdf_dout(rdf_dout),.sdram_rd_req(sdram_rd_req),.syswr_done(syswr_done),.tx_start(tx_start));//------------------------------------------------//例化模拟写入数据到sdram模块wire syswr_done; //所有数据写入sdram完成标志位datagene uut_datagene(.clk(clk_25m),.rst_n(sys_rst_n),.wrf_din(wrf_din),.wrf_wrreq(wrf_wrreq),.moni_addr(sys_addr),.syswr_done(syswr_done),.sdram_rd_ack(sdram_rd_ack));//------------------------------------------------//例化串口数据发送控制模块wire tx_start; //串口发送数据启动标志位,高有效uart_ctrl uut_uartctrl(.clk(clk_25m),.rst_n(sys_rst_n),.tx_data(rdf_dout[7:0]),.tx_start(tx_start), ///////////.fifo232_rdreq(rdf_rdreq),.rs232_tx(rs232_tx));Endmodulemodule datagene(clk,rst_n,wrf_din,wrf_wrreq,moni_addr,syswr_done,sdram_rd_ack);input clk; //FPAG输入时钟信号25MHzinput rst_n; //FPGA输入复位信号//wrFIFO输入控制接口output[15:0] wrf_din; //sdram数据写入缓存FIFO输入数据总线output wrf_wrreq; //sdram数据写入缓存FIFO数据输入请求,高有效output[21:0] moni_addr; //sdram读写地址产生output syswr_done; //所有数据写入sdram完成标志位input sdram_rd_ack; //系统读SDRAM响应信号,作为rdFIFO的输写有效信号,这里捕获它的下降沿作为读地址自增加标志位reg sdr_rdackr1,sdr_rdackr2;//------------------------------------------//捕获sdram_rd_ack下降沿标志位always @(posedge clk or negedge rst_n)if(!rst_n) beginsdr_rdackr1 <= 1'b0;sdr_rdackr2 <= 1'b0;endelse beginsdr_rdackr1 <= sdram_rd_ack;sdr_rdackr2 <= sdr_rdackr1;endwire neg_rdack = ~sdr_rdackr1 & sdr_rdackr2;//------------------------------------------//上电500us延时等待sdram就绪reg[13:0] delay; //500us延时计数器always @(posedge clk or negedge rst_n)if(!rst_n) delay <= 14'd0;else if(delay < 14'd12500) delay <= delay+1'b1;wire delay_done = (delay == 14'd12500); //1ms延时结束//------------------------------------------//每640ns写入8个16bit数据到sdram,//上电后所有地址写入完毕时间需要不到360ms时间reg[5:0] cntwr; //写sdram定时计数器always @(posedge clk or negedge rst_n)if(!rst_n) cntwr <= 6'd0;else if(delay_done) cntwr <= cntwr+1'b1;//------------------------------------------//读写sdram地址产生reg[18:0] addr; //sdram地址寄存器always @(posedge clk or negedge rst_n)if(!rst_n) addr <= 19'd0;else if(!wr_done && cntwr == 6'h3f) addr <= addr+1'b1;//写地址产生else if(wr_done && neg_rdack) addr <= addr+1'b1; //读地址产生////////////testassign moni_addr = {addr,3'b000};reg wr_done; //所有数据写入sdram完成标志位always @(posedge clk or negedge rst_n)if(!rst_n) wr_done <= 1'b0;else if(addr == 19'h7ffff) wr_done <= 1'b1;assign syswr_done = wr_done;//------------------------------------------//写sdram请求信号产生,即wrfifo的写入有效信号reg wrf_wrreqr; //wrfifo的写入有效信号reg[15:0] wrf_dinr; //wrfifo的写入数据always @(posedge clk or negedge rst_n)if(!rst_n) wrf_wrreqr <= 1'b0;else if(!wr_done) begin //上电0.5ms延时完成if(cntwr == 6'h05) wrf_wrreqr <= 1'b1; //写请求信号产生else if(cntwr == 6'h0d) wrf_wrreqr <= 1'b0; //请求信号撤销endalways @(posedge clk or negedge rst_n)if(!rst_n) wrf_dinr <= 16'd0;else if(!wr_done && ((cntwr > 6'h05) && (cntwr <= 6'h0d))) begin //上电0.5ms延时完成wrf_dinr <= wrf_dinr+1'b1; //写入数据递增endassign wrf_wrreq = wrf_wrreqr;assign wrf_din = wrf_dinr;endmodulemodule sdram_ctrl(clk,rst_n,/*sdram_udqm,sdram_ldqm,*/sdram_wr_req,sdram_rd_req,sdram_wr_ack,sdram_rd_ack,sdram_busy,sys_dout_rdy,init_state,work_state,cnt_clk);//系统信号接口input clk; //系统时钟,50MHzinput rst_n; //复位信号,低电平有效// SDRAM硬件接口//output sdram_udqm; // SDRAM高字节屏蔽//output sdram_ldqm; // SDRAM低字节屏蔽// SDRAM封装接口input sdram_wr_req; //系统写SDRAM请求信号input sdram_rd_req; //系统读SDRAM请求信号output sdram_wr_ack; //系统写SDRAM响应信号,作为wrFIFO的输出有效信号output sdram_rd_ack; //系统读SDRAM响应信号//output sdram_ref_w; // SDRAM自刷新请求信号output sdram_busy; // SDRAM忙标志位,高表示忙output sys_dout_rdy; // SDRAM数据输出完成标志// SDRAM内部接口output[4:0] init_state; // SDRAM初始化寄存器output[3:0] work_state; // SDRAM工作状态寄存器output[8:0] cnt_clk; //时钟计数wire done_200us; //上电后200us输入稳定期结束标志位wire sdram_init_done; // SDRAM初始化完成标志,高表示完成wire sdram_busy; // SDRAM忙标志,高表示SDRAM处于工作中reg sdram_ref_req; // SDRAM自刷新请求信号wire sdram_ref_ack; // SDRAM自刷新请求应答信号`include "sdr_para.v" // 包含SDRAM参数定义模块// SDRAM时序延时参数parameter TRP_CLK = 9'd4,//1, //TRP=18ns预充电有效周期TRFC_CLK = 9'd6,//3, //TRC=60ns自动预刷新周期TMRD_CLK = 9'd6,//2, //模式寄存器设置等待时钟周期TRCD_CLK = 9'd2,//1, //TRCD=18ns行选通周期TCL_CLK = 9'd3, //潜伏期TCL_CLK=3个CLK,在初始化模式寄存器中可设置TREAD_CLK = 9'd8, //突发读数据周期256CLKTWRITE_CLK = 9'd8, //突发写数据256CLKTDAL_CLK = 9'd3; //写入等待//------------------------------------------------------------------------------//assign sdram_udqm = 1'b0; // SDRAM数据高字节有效//assign sdram_ldqm = 1'b0; // SDRAM数据低字节有效//------------------------------------------------------------------------------//上电后200us计时,计时时间到,则done_200us=1//------------------------------------------------------------------------------reg[14:0] cnt_200us;always @ (posedge clk or negedge rst_n)if(!rst_n) cnt_200us <= 15'd0;else if(cnt_200us < 15'd20_000) cnt_200us <= cnt_200us+1'b1; //计数assign done_200us = (cnt_200us == 15'd20_000); //条件满足则done_200us=1//------------------------------------------------------------------------------//SDRAM的初始化操作状态机//------------------------------------------------------------------------------reg[4:0] init_state_r; // SDRAM初始化状态always @ (posedge clk or negedge rst_n)if(!rst_n) init_state_r <= `I_NOP;elsecase (init_state_r)`I_NOP: i nit_state_r <= done_200us ? `I_PRE:`I_NOP; //上电复位后200us结束则进入下一状态`I_PRE: init_state_r <= (TRP_CLK == 0) ? `I_AR1:`I_TRP; //预充电状态`I_TRP: init_state_r <= (`end_trp) ? `I_AR1:`I_TRP; //预充电等待TRP_CLK个时钟周期`I_AR1: init_state_r <= (TRFC_CLK == 0) ? `I_AR2:`I_TRF1; //第1次自刷新`I_TRF1: init_state_r <= (`end_trfc) ? `I_AR2:`I_TRF1; //等待第1次自刷新结束,TRFC_CLK个时钟周期`I_AR2: init_state_r <= (TRFC_CLK == 0) ? `I_AR3:`I_TRF2; //第2次自刷新`I_TRF2: init_state_r <= (`end_trfc) ? `I_AR3:`I_TRF2; //等待第2次自刷新结束,TRFC_CLK个时钟周期`I_AR3: init_state_r <= (TRFC_CLK == 0) ? `I_AR4:`I_TRF3; //第3次自刷新`I_TRF3: init_state_r <= (`end_trfc) ? `I_AR4:`I_TRF3; //等待第3次自刷新结束,TRFC_CLK个时钟周期`I_AR4: init_state_r <= (TRFC_CLK == 0) ? `I_AR5:`I_TRF4; //第4次自刷新`I_TRF4: init_state_r <= (`end_trfc) ? `I_AR5:`I_TRF4; //等待第4次自刷新结束,TRFC_CLK个时钟周期`I_AR5: init_state_r <= (TRFC_CLK == 0) ? `I_AR6:`I_TRF5; //第5次自刷新`I_TRF5: init_state_r <= (`end_trfc) ? `I_AR6:`I_TRF5; //等待第5次自刷新结束,TRFC_CLK个时钟周期`I_AR6: init_state_r <= (TRFC_CLK == 0) ? `I_AR7:`I_TRF6; //第6次自刷新`I_TRF6: init_state_r <= (`end_trfc) ? `I_AR7:`I_TRF6; //等待第6次自刷新结束,TRFC_CLK个时钟周期`I_AR7: init_state_r <= (TRFC_CLK == 0) ? `I_AR8:`I_TRF7; //第7次自刷新`I_TRF7: init_state_r <= (`end_trfc) ? `I_AR8:`I_TRF7; //等待第7次自刷新结束,TRFC_CLK个时钟周期`I_AR8: init_state_r <= (TRFC_CLK == 0) ? `I_MRS:`I_TRF8; //第8次自刷新`I_TRF8: init_state_r <= (`end_trfc) ? `I_MRS:`I_TRF8; //等待第8次自刷新结束,TRFC_CLK个时钟周期`I_MRS: init_state_r <= (TMRD_CLK == 0) ? `I_DONE:`I_TMRD;//模式寄存器设置(MRS)`I_TMRD: init_state_r <= (`end_tmrd) ? `I_DONE:`I_TMRD; //等待模式寄存器设置完成,TMRD_CLK个时钟周期`I_DONE: init_state_r <= `I_DONE; // SDRAM的初始化设置完成标志default: init_state_r <= `I_NOP;endcaseassign init_state = init_state_r;assign sdram_init_done = (init_state_r == `I_DONE); // SDRAM初始化完成标志//------------------------------------------------------------------------------//15us计时,每60ms全部4096行存储区进行一次自刷新// ( 存储体中电容的数据有效保存期上限是64ms )//------------------------------------------------------------------------------reg[10:0] cnt_15us; //计数寄存器always @ (posedge clk or negedge rst_n)if(!rst_n) cnt_15us <= 11'd0;else if(cnt_15us < 11'd1499) cnt_15us <= cnt_15us+1'b1; // 60ms(64ms)/4096=15us循环计数else cnt_15us <= 11'd0;always @ (posedge clk or negedge rst_n)if(!rst_n) sdram_ref_req <= 1'b0;else if(cnt_15us == 11'd1498) sdram_ref_req <= 1'b1; //产生自刷新请求else if(sdram_ref_ack) sdram_ref_req <= 1'b0; //已响应自刷新//------------------------------------------------------------------------------//SDRAM的读写以及自刷新操作状态机//------------------------------------------------------------------------------reg[3:0] work_state_r; // SDRAM读写状态reg sys_r_wn; // SDRAM读/写控制信号always @ (posedge clk or negedge rst_n) beginif(!rst_n) work_state_r <= `W_IDLE;elsecase (work_state_r)`W_IDLE: if(sdram_ref_req & sdram_init_done) beginwork_state_r <= `W_AR; //定时自刷新请求sys_r_wn <= 1'b1;endelse if(sdram_wr_req & sdram_init_done) beginwork_state_r <= `W_ACTIVE;//写SDRAMsys_r_wn <= 1'b0;endelse if(sdram_rd_req && sdram_init_done) beginwork_state_r <= `W_ACTIVE;//读SDRAMsys_r_wn <= 1'b1;endelse beginwork_state_r <= `W_IDLE;sys_r_wn <= 1'b1;end//行有效状态`W_ACTIVE: if(TRCD_CLK == 0)if(sys_r_wn) work_state_r <= `W_READ;else work_state_r <= `W_WRITE;else work_state_r <= `W_TRCD;`W_TRCD: if(`end_trcd)if(sys_r_wn) work_state_r <= `W_READ;else work_state_r <= `W_WRITE;else work_state_r <= `W_TRCD;// SDRAM读数据状态`W_READ: work_state_r <= `W_CL;`W_CL: work_state_r <= (`end_tcl) ? `W_RD:`W_CL;`W_RD: work_state_r <= (`end_tread) ? `W_RW AIT:`W_RD; //后面需要添加一个读完成后的预充电等待状态`W_RWAIT: work_state_r <= (`end_trwait) ? `W_IDLE:`W_RWAIT;// SDRAM写数据状态`W_WRITE: work_state_r <= `W_WD;`W_WD: work_state_r <= (`end_twrite) ? `W_TDAL:`W_WD;`W_TDAL: work_state_r <= (`end_tdal) ? `W_IDLE:`W_TDAL;// SDRAM自动刷新状态`W_AR: work_state_r <= (TRFC_CLK == 0) ? `W_IDLE:`W_TRFC;`W_TRFC: work_state_r <= (`end_trfc) ? `W_IDLE:`W_TRFC;default: work_state_r <= `W_IDLE;endcaseendassign work_state = work_state_r; // SDRAM工作状态寄存器assign sdram_busy = (sdram_init_done && work_state_r == `W_IDLE) ? 1'b0:1'b1; // SDRAM忙标志位assign sdram_ref_ack = (work_state_r == `W_AR); // SDRAM自刷新应答信号assign sdram_wr_ack = ((work_state == `W_TRCD) & ~sys_r_wn) | (work_state == `W_WRITE)| ((work_state == `W_WD) & (cnt_clk_r < 9'd6)); //写SDRAM 响应信号,作为wrFIFO的输出有效信号assign sdram_rd_ack = (work_state_r == `W_RD) & (cnt_clk_r > 9'd1) & (cnt_clk_r < 9'd10);//读SDRAM响应信号assign sys_dout_rdy = (work_state_r == `W_RD && `end_tread); // SDRAM数据输出完成标志//------------------------------------------------------------------------------//产生SDRAM时序操作的延时//------------------------------------------------------------------------------reg[8:0] cnt_clk_r; //时钟计数reg cnt_rst_n; //时钟计数复位信号always @ (posedge clk or negedge rst_n)if(!rst_n) cnt_clk_r <= 9'd0; //计数寄存器复位else if(!cnt_rst_n) cnt_clk_r <= 9'd0; //计数寄存器清零else cnt_clk_r <= cnt_clk_r+1'b1; //启动计数延时assign cnt_clk = cnt_clk_r; //计数寄存器引出,内部`define中使用//计数器控制逻辑always @ (init_state_r or work_state_r or cnt_clk_r) begincase (init_state_r)`I_NOP: cnt_rst_n <= 1'b0;`I_PRE: cnt_rst_n <= (TRP_CLK != 0);//预充电延时计数启动`I_TRP: cnt_rst_n <= (`end_trp) ? 1'b0:1'b1; //等待预充电延时计数结束后,清零计数器`I_AR1,`I_AR2,`I_AR3,`I_AR4,`I_AR5,`I_AR6,`I_AR7,`I_AR8:cnt_rst_n <= (TRFC_CLK != 0); //自刷新延时计数启动`I_TRF1,`I_TRF2,`I_TRF3,`I_TRF4,`I_TRF5,`I_TRF6,`I_TRF7,`I_TRF8:cnt_rst_n <= (`end_trfc) ? 1'b0:1'b1; //等待自刷新延时计数结束后,清零计数器`I_MRS: cnt_rst_n <= (TMRD_CLK != 0); //模式寄存器设置延时计数启动`I_TMRD: cnt_rst_n <= (`end_tmrd) ? 1'b0:1'b1; //等待自刷新延时计数结束后,清零计数器`I_DONE:case (work_state_r)`W_IDLE: cnt_rst_n <= 1'b0;`W_ACTIVE: cnt_rst_n <= (TRCD_CLK == 0) ? 1'b0:1'b1;`W_TRCD: cnt_rst_n <= (`end_trcd) ? 1'b0:1'b1;`W_CL: cnt_rst_n <= (`end_tcl) ? 1'b0:1'b1;`W_RD: cnt_rst_n <= (`end_tread) ? 1'b0:1'b1;`W_RWAIT: cnt_rst_n <= (`end_trwait) ? 1'b0:1'b1;`W_WD: cnt_rst_n <= (`end_twrite) ? 1'b0:1'b1;`W_TDAL: cnt_rst_n <= (`end_tdal) ? 1'b0:1'b1;`W_TRFC: cnt_rst_n <= (`end_trfc) ? 1'b0:1'b1;default: cnt_rst_n <= 1'b0;endcasedefault: cnt_rst_n <= 1'b0;endcaseendendmodulemodule sdram_cmd(clk,rst_n,sdram_cke,sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n,sdram_ba,sdram_addr,sys_addr,init_state,work_state);//系统信号input clk; //50MHzinput rst_n; //低电平复位信号// SDRAM硬件接口output sdram_cke; // SDRAM时钟有效信号output sdram_cs_n; // SDRAM片选信号output sdram_ras_n; // SDRAM行地址选通脉冲output sdram_cas_n; // SDRAM列地址选通脉冲output sdram_we_n; // SDRAM写允许位output[1:0] sdram_ba; // SDRAM的L-Bank地址线output[11:0] sdram_addr; // SDRAM地址总线// SDRAM封装接口input[21:0] sys_addr; // 读写SDRAM时地址暂存器,(bit21-20)L-Bank地址:(bit19-8)为行地址,(bit7-0)为列地址// SDRAM内部接口input[4:0] init_state; // SDRAM初始化状态寄存器input[3:0] work_state; // SDRAM读写状态寄存器`include "sdr_para.v" // 包含SDRAM参数定义模块//-------------------------------------------------------------------------------//-------------------------------------------------------------------------------reg[4:0] sdram_cmd_r; // SDRAM操作命令reg[1:0] sdram_ba_r;reg[11:0] sdram_addr_r;assign {sdram_cke,sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n} = sdram_cmd_r; assign sdram_ba = sdram_ba_r;assign sdram_addr = sdram_addr_r;//-------------------------------------------------------------------------------//SDRAM命令参数赋值always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginsdram_cmd_r <= `CMD_INIT;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;endelsecase (init_state)`I_NOP,`I_TRP,`I_TRF1,`I_TRF2,`I_TRF3,`I_TRF4,`I_TRF5,`I_TRF6,`I_TRF7,`I_TRF8,`I _TMRD: beginsdram_cmd_r <= `CMD_NOP;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;end`I_PRE: beginsdram_cmd_r <= `CMD_PRGE;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;end`I_AR1,`I_AR2,`I_AR3,`I_AR4,`I_AR5,`I_AR6,`I_AR7,`I_AR8: beginsdram_cmd_r <= `CMD_A_REF;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;end`I_MRS: begin //模式寄存器设置,可根据实际需要进行设置sdram_cmd_r <= `CMD_LMR;sdram_ba_r <= 2'b00; //操作模式设置sdram_addr_r <= {2'b00, //操作模式设置1'b0, //操作模式设置(这里设置为A9=0,即突发读/突发写)2'b00, //操作模式设置({A8,A7}=00),当前操作为模式寄存器设置3'b011, // CAS潜伏期设置(这里设置为3,{A6,A5,A4}=011)1'b0, //突发传输方式(这里设置为顺序,A3=b0)3'b011 //突发长度(这里设置为8,{A2,A1,A0}=011)};end`I_DONE:case (work_state)`W_IDLE,`W_TRCD,`W_CL,`W_TRFC,`W_RD,`W_WD,`W_TDAL: beginsdram_cmd_r <= `CMD_NOP;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;end`W_ACTIVE: beginsdram_cmd_r <= `CMD_ACTIVE;sdram_ba_r <= sys_addr[21:20]; //L-Bank地址sdram_addr_r <= sys_addr[19:8]; //行地址end`W_READ: beginsdram_cmd_r <= `CMD_READ;sdram_ba_r <= sys_addr[21:20]; //L-Bank地址sdram_addr_r <= {4'b0100, // A10=1,设置写完成允许预充电sys_addr[7:0] //列地址};end`W_WRITE: beginsdram_cmd_r <= `CMD_WRITE;sdram_ba_r <= sys_addr[21:20]; //L-Bank地址sdram_addr_r <= {4'b0100, // A10=1,设置写完成允许预充电sys_addr[7:0] //列地址};end`W_AR: beginsdram_cmd_r <= `CMD_A_REF;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;enddefault: beginsdram_cmd_r <= `CMD_NOP;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;endendcasedefault: beginsdram_cmd_r <= `CMD_NOP;sdram_ba_r <= 2'b11;sdram_addr_r <= 12'hfff;endendcaseendendmodulemodule sdram_wr_data(clk,rst_n,/*sdram_clk,*/sdram_data,sys_data_in,sys_data_out,work_state,cnt_clk);//系统信号input clk; //系统时钟,100MHzinput rst_n; //复位信号,低电平有效// SDRAM硬件接口//output sdram_clk; // SDRAM时钟信号inout[15:0] sdram_data; // SDRAM数据总线// SDRAM封装接口input[15:0] sys_data_in; //写SDRAM时数据暂存器output[15:0] sys_data_out; //读SDRAM时数据暂存器// SDRAM内部接口input[3:0] work_state; //读写SDRAM时数据状态寄存器input[8:0] cnt_clk; //时钟计数`include "sdr_para.v" // 包含SDRAM参数定义模块//assign sdram_clk = ~clk; // SDRAM时钟信号//------------------------------------------------------------------------------//数据写入控制//------------------------------------------------------------------------------reg[15:0] sdr_din; //突发数据写寄存器reg sdr_dlink; // SDRAM数据总线输入输出控制//将待写入数据送到SDRAM数据总线上always @ (posedge clk or negedge rst_n)if(!rst_n) sdr_din <= 16'd0; //突发数据写寄存器复位else if((work_state == `W_WRITE) | (work_state == `W_WD)) sdr_din <= sys_data_in;//连续写入存储在wrFIFO中的256个16bit数据//产生双向数据线方向控制逻辑always @ (posedge clk or negedge rst_n)if(!rst_n) sdr_dlink <= 1'b0;else if((work_state == `W_WRITE) | (work_state == `W_WD)) sdr_dlink <= 1'b1;else sdr_dlink <= 1'b0;assign sdram_data = sdr_dlink ? sdr_din:16'hzzzz;//------------------------------------------------------------------------------//数据读出控制//------------------------------------------------------------------------------reg[15:0] sdr_dout; //突发数据读寄存器//将数据从SDRAM读出always @ (posedge clk or negedge rst_n)if(!rst_n) sdr_dout <= 16'd0; //突发数据读寄存器复位else if((work_state == `W_RD) & (cnt_clk > 9'd0) & (cnt_clk < 9'd10)) sdr_dout <= sdram_data; //连续读出256B的16bit数据存储到rdFIFO中assign sys_data_out = sdr_dout;//------------------------------------------------------------------------------Endmodulemodule sys_ctrl(clk,rst_n,sys_rst_n,clk_25m,clk_100m,sdram_clk);input clk; //FPAG输入时钟信号25MHzinput rst_n; //FPGA输入复位信号output sys_rst_n; //系统复位信号,低有效output clk_25m; //PLL输出25MHz时钟output clk_100m; //PLL输出100MHz时钟output sdram_clk; //用于外部SDAM的时钟100Mwire locked; //PLL输出有效标志位,高表示PLL输出有效//----------------------------------------------//PLL复位信号产生,高有效//异步复位,同步释放wire pll_rst; //PLL复位信号,高有效reg rst_r1,rst_r2;always @(posedge clk or negedge rst_n)if(!rst_n) rst_r1 <= 1'b1;else rst_r1 <= 1'b0;always @(posedge clk or negedge rst_n)if(!rst_n) rst_r2 <= 1'b1;else rst_r2 <= rst_r1;assign pll_rst = rst_r2;//----------------------------------------------//系统复位信号产生,低有效//异步复位,同步释放wire sys_rst_n; //系统复位信号,低有效wire sysrst_nr0;reg sysrst_nr1,sysrst_nr2;assign sysrst_nr0 = rst_n & locked; //系统复位直到PLL有效输出always @(posedge clk_100m or negedge sysrst_nr0)if(!sysrst_nr0) sysrst_nr1 <= 1'b0;else sysrst_nr1 <= 1'b1;always @(posedge clk_100m or negedge sysrst_nr0)if(!sysrst_nr0) sysrst_nr2 <= 1'b0;else sysrst_nr2 <= sysrst_nr1;assign sys_rst_n = sysrst_nr2;//----------------------------------------------//例化PLL产生模块PLL_ctrl uut_PLL_ctrl(.areset(pll_rst), //PLL复位信号,高电平复位.inclk0(clk), //PLL输入时钟,25MHz.c0(clk_25m), //PLL输出25MHz时钟.c1(clk_100m), //PLL输出100MHz时钟.e0(sdram_clk), //用于外部SDAM的时钟100M.locked(locked) //PLL输出有效标志位,高表示PLL输出有效);endmodulemodule uart_ctrl(clk,rst_n,tx_data,tx_start,fifo232_rdreq,rs232_tx);input clk; // 25MHz主时钟input rst_n; //低电平复位信号input[7:0] tx_data; //待发送数据input tx_start; //串口发送数据启动标志位,高有效output fifo232_rdreq; //FIFO读请求信号,高有效output rs232_tx; //RS232发送数据信号//----------------------------------------------------------------//串口发送底层模块和串口波特率选择模块接口wire clk_bps; //发送数据标志位,高有效wire bps_start; //波特率时钟计数器启动信号,高有效//----------------------------------------------------------------//例化串口数据发送底层模块uart_tx uut_tx(.clk(clk),.rst_n(rst_n),.tx_data(tx_data),.tx_start(tx_start),.clk_bps(clk_bps),.rs232_tx(rs232_tx),.bps_start(bps_start),.fifo232_rdreq(fifo232_rdreq));//例化串口数据发送波特率控制模块uart_speed_select uut_ss(.clk(clk),.rst_n(rst_n),.bps_start(bps_start),.clk_bps(clk_bps));Endmodulemodule sdfifo_ctrl(clk_25m,clk_100m,wrf_din,wrf_wrreq,sdram_wr_ack,/*sys_addr,*/sys_data_in,sdram_wr_req,sys_data_out,rdf_rdreq,sdram_rd_ack,rdf_dout,sdram_rd_req,syswr_done,tx_start);input clk_25m; //PLL输出25MHz时钟input clk_100m; //PLL输出100MHz时钟//wrfifoinput[15:0] wrf_din; //sdram数据写入缓存FIFO输入数据总线input wrf_wrreq; //sdram数据写入缓存FIFO数据输入请求,高有效input sdram_wr_ack; //系统写SDRAM响应信号,作为wrFIFO的输出有效信号//output[21:0] sys_addr; //读写SDRAM时地址暂存器,(bit21-20)L-Bank地址:(bit19-8)为行地址,(bit7-0)为列地址output[15:0] sys_data_in; //sdram数据写入缓存FIFO输出数据总线,即写SDRAM时数据暂存器output sdram_wr_req; //系统写SDRAM请求信号//rdfifoinput[15:0] sys_data_out; //sdram数据读出缓存FIFO输入数据总线input rdf_rdreq; //sdram数据读出缓存FIFO数据输出请求,高有效input sdram_rd_ack; //系统读SDRAM响应信号,作为rdFIFO的输写有效信号output[15:0] rdf_dout; //sdram数据读出缓存FIFO输出数据总线output sdram_rd_req; //系统读SDRAM请求信号input syswr_done; //所有数据写入sdram完成标志位output tx_start; //串口发送数据启动标志位,高有效//------------------------------------------------wire[8:0] wrf_use; //sdram数据写入缓存FIFO已用存储空间数量wire[8:0] rdf_use; //sdram数据读出缓存FIFO已用存储空间数量//assign sys_addr = 22'h1a9e21; //测试用assign sdram_wr_req = ((wrf_use >= 9'd8) & ~syswr_done); //FIFO(8个16bit数据)即发出写SDRAM请求信号assign sdram_rd_req = ((rdf_use <= 9'd256) & syswr_done); //sdram写入完成且FIFO半空(256个16bit数据)即发出读SDRAM请求信号assign tx_start = ((rdf_use != 9'd0) & syswr_done); //启动串口发送数据//------------------------------------------------//例化SDRAM写入数据缓存FIFO模块wrfifo uut_wrfifo(.data(wrf_din),.rdclk(clk_100m),.rdreq(sdram_wr_ack),.wrclk(clk_25m),.wrreq(wrf_wrreq),.q(sys_data_in),.wrusedw(wrf_use));//------------------------------------------------//例化SDRAM读出数据缓存FIFO模块rdfifo uut_rdfifo(.data(sys_data_out),.rdclk(clk_25m),.rdreq(rdf_rdreq),.wrclk(clk_100m),.wrreq(/*rdf_wrreq*/sdram_rd_ack),.q(rdf_dout),.wrusedw(rdf_use));endmodule。
Verilog编码规范(仅供内部使用)拟制: xxx 日期:xxx审核: 审核者日期:yyyy-mm-dd 批准: 批准者日期:yyyy-mm-dd版权所有侵权必究修订记录目录1命名规范 (6)2代码编写规范 (8)2.1 版面 (8)2.2 编写代码规范 (8)3电路设计规则 (16)3.1 时钟 (16)3.2 复位 (17)3.3 避免LATCH (18)3.4 避免组合反馈 (18)3.5 赋值语句 (18)3.6 case语句和if-then-else语句 (18)3.7 状态机 (19)3.8 异步逻辑 (20)4模块划分 (21)5提高可移植性的编码风格 (21)5.1 采用参数化设计 (21)5.2 采用独立于工具平台和工艺库的设计 (22)5.3 尽量使用已经得到验证的IP (22)6其他一些设计建议 (22)7附件 (24)8参考文档: (28)基本原则:简单,一致,可重用。
●简单指尽量使用简单的语句,尽量使用简单的设计,尽量使用简单的时钟,尽量使用简单的复位。
●一致指尽量保持代码风格一致,尽量保持命名一致。
●可重用指有成熟的IP尽量使用IP,设计的代码要尽量可重用。
1命名规范给信号命名就像给孩子取名字一样,有区别,有根源,有深度,还有一点,要简单,别冗长。
有区别指取名字不要一样,假如大家只有一个手机号码,那这个号码还能有什么用处?有根源指取名字要能象姓氏一样,让人一看就直到是张家的后代而不是李家的。
有深度就是取名字要有涵义,张一,张二,张三虽然也是名字,但是请考虑一下被取名字人的感受。
简单点,几十个字母长的名字,打字的和看字的都累。
♦大小写规则:只有parameter,`define和module名称才能享受大写。
♦Module 名应与文件名保持一致(文件名是小写),假如不想在设计后面遇到麻烦的话。
♦不要尝试使用任何保留字,因为他们已经被保留了。
♦不要重复使用同样的名字去命名不同的数据。
Verilog是一种硬件描述语言,用于描述数字电路和系统的行为和结构。
它被广泛用于集成电路设计、数字信号处理、嵌入式系统等领域。
下面是对Verilog源码的
一些解读。
1.模块化设计
Verilog源码通常由多个模块组成,每个模块描述一个独立的电路或系统。
模块可以使用其他模块,这使得代码可以被重复使用和组合。
每个模块都有一个关键字module,其后跟着模块名称和输入输出端口列表。
2.层次结构
Verilog源码具有层次结构,可以使用实例化的方法将模块组合成更复杂的电路。
这使得设计更加模块化和可维护。
3.信号赋值
Verilog源码中的信号可以通过赋值语句进行赋值。
赋值语句可以是连续赋值或过程赋值。
连续赋值使用“=”运算符将一个信号的值设置为另一个信号的值,而过程赋值使用“<=”运算符将一个信号的值设置为另一个信号的值,但只在每个时钟周
期的上升沿触发。
4.条件语句和循环语句
Verilog源码中可以使用条件语句和循环语句来控制代码的执行。
条件语句使用if-else结构或case语句,而循环语句使用for循环或while循环。
5.任务和函数
Verilog源码中可以使用任务和函数来封装重复的代码。
任务和函数可以在模块内部定义,也可以在模块外部定义并在模块内部调用。
总之,Verilog源码是一种结构化和模块化的硬件描述语言,用于描述数字电路和系统的行为和结构。
通过理解和掌握Verilog语言的语法和语义,可以更好地设计和实现复杂的数字电路和系统。