verilog源码积累:ram和axi slaver
- ram可以改写成可读可写的memory模型
- ramv
- axi slaverv
这两个代码,用过,觉得不错。收下。
ed2-ram00/ram.v at master · samlnx03/ed2-ram00 · GitHub
https://github.com/samlnx03/ed2-ram00/blob/master/ram.vuvm_axi/axi_slave.v at master · funningboy/uvm_axi · GitHub
https://github.com/funningboy/uvm_axi/blob/master/v/axi_slave.v
ram可以改写成可读可写的memory模型
主要是配合$readmemh,$fopen,$fdisplay
。
参考文档:
- Verilog中文件输入与输出任务实例解析一只大笨鹅新浪博客
http://blog.sina.com.cn/s/blog_032253000100p5in.html
ram.v
`timescale 1ns / 1ps
//-----------------------------------------------------
// Design Name : ram_sp_sr_sw
// File Name : ram_sp_sr_sw.v
// Function : Synchronous read write RAM
// Coder : Deepak Kumar Tala
//-----------------------------------------------------
module ram_sp_sr_sw (
clk , // Clock Input
address , // Address Input
data , // Data bi-directional
cs , // Chip Select
we , // Write Enable/Read Enable
oe // Output Enable
); parameter DATA_WIDTH = 5 ;
parameter ADDR_WIDTH = 5 ;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;//--------------Input Ports-----------------------
input clk ;
input [ADDR_WIDTH-1:0] address ;
input cs ;
input we ;
input oe ; //--------------Inout Ports-----------------------
inout [DATA_WIDTH-1:0] data ;//--------------Internal variables----------------
reg [DATA_WIDTH-1:0] data_out ;
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
reg oe_r;//--------------Code Starts Here------------------ initial $readmemh("ram_init.txt",mem); // initialize readback from a file// Tri-State Buffer control
// output : When we = 0, oe = 1, cs = 1
assign data = (cs && oe_r && !we) ? data_out : {DATA_WIDTH{1'bz}}; // Memory Write Block
// Write Operation : When we = 1, cs = 1
always @ (posedge clk)
begin : MEM_WRITEif ( cs && we ) beginmem[address] = data;end
end// Memory Read Block
// Read Operation : When we = 0, oe = 1, cs = 1
always @ (posedge clk)
begin : MEM_READif (cs && !we && oe) begindata_out = mem[address];oe_r = 1;end else beginoe_r = 0;end
endendmodule // End of Module ram_sp_sr_sw
axi slaver.v
`timescale 1ns/10psmodule axi_slave
#(
parameter AXI_ID_WIDTH = 4
)
(clk,rstn,// AXI write address channeli_awaddr,i_awid,i_awlen,i_awvalid,o_awready,// AXI write data channeli_wdata,i_wid,i_wstrb,i_wlast,i_wvalid,o_wready,o_bresp,o_bid,o_bvalid,i_bready,// AXI read address channeli_araddr,i_arid,i_arlen,i_arvalid,o_arready,// AXI read data channelo_rdata,o_rid,o_rresp,o_rlast,o_rvalid,i_rready
);input clk;
input rstn;// AXI write address channel
input [31:0] i_awaddr;
input [AXI_ID_WIDTH-1:0] i_awid;
input [3:0] i_awlen;
input i_awvalid;
output o_awready;// AXI write data channel
input [31:0] i_wdata;
input [AXI_ID_WIDTH-1:0] i_wid;
input [3:0] i_wstrb;
input i_wlast;
input i_wvalid;
output o_wready;
output [AXI_ID_WIDTH-1:0] o_bid;
output [1:0] o_bresp;
output o_bvalid;
input i_bready;// AXI read address channel
input [31:0] i_araddr;
input [AXI_ID_WIDTH-1:0] i_arid;
input [3:0] i_arlen;
input i_arvalid;
output o_arready;// AXI read data channel
output [31:0] o_rdata;
output [AXI_ID_WIDTH-1:0] o_rid;
output [1:0] o_rresp;
output o_rlast;
output o_rvalid;
input i_rready;parameter ST_R_IDLE = 3'd0;
parameter ST_R_PRE1 = 3'd1;
parameter ST_R_PRE2 = 3'd2;
parameter ST_R_PRE3 = 3'd3;
parameter ST_R_READ = 3'd4;
parameter ST_R_END = 3'd5;parameter ST_W_IDLE = 3'd0;
parameter ST_W_PRE1 = 3'd1;
parameter ST_W_PRE2 = 3'd2;
parameter ST_W_PRE3 = 3'd3;
parameter ST_W_WRITE = 3'd4;
parameter ST_W_END = 3'd5;reg [2:0] r_cs;
reg [2:0] r_ns;
reg [2:0] w_cs;
reg [2:0] w_ns;reg [3:0] rdcnt;
reg [31:0] araddr;
reg [3:0] arlen;
reg [AXI_ID_WIDTH-1:0] arid;reg [3:0] wdcnt;
reg [31:0] awaddr;
reg [3:0] awlen;
reg [AXI_ID_WIDTH-1:0] awid;reg [5:0] axi_wait_cnt_0;
reg [5:0] axi_wait_cnt_1;
reg [5:0] axi_wait_num_0;
reg [5:0] axi_wait_num_1;
reg [31:0] rdn_num_0;
reg [31:0] rdn_num_1;reg [31:0] o_rdata;
reg [31:0] mem[63:0];initial begin$mem_alloc();
endalways@(posedge clk or negedge rstn) beginif (!rstn) beginrdn_num_0 <= 32'd0;rdn_num_1 <= 32'd0;end else beginrdn_num_0 <= $random;rdn_num_1 <= $random;end
endalways@(posedge clk or negedge rstn) beginif (!rstn) beginaxi_wait_cnt_0 <= 6'd0;axi_wait_num_0 <= 6'd8;end else if (i_arvalid & o_arready) beginaxi_wait_cnt_0 <= 6'd0;axi_wait_num_0 <= rdn_num_0[5:0];end else if (i_arvalid & !o_arready) beginif (axi_wait_cnt_0==axi_wait_num_0) beginaxi_wait_cnt_0 <= 5'd0;end else beginaxi_wait_cnt_0 <= axi_wait_cnt_0 + 1'b1;endend
endalways@(posedge clk or negedge rstn) beginif (!rstn) beginaxi_wait_cnt_1 <= 6'd0;axi_wait_num_1 <= 6'd8;end else if (i_awvalid & o_awready) beginaxi_wait_cnt_1 <= 6'd0;axi_wait_num_1 <= rdn_num_1[5:0];end else if (i_awvalid & !o_awready) beginif (axi_wait_cnt_1==axi_wait_num_1) beginaxi_wait_cnt_1 <= 5'd0;end else beginaxi_wait_cnt_1 <= axi_wait_cnt_1 + 1'b1;endend
end//------------------------------------------------------------------------------------------------
`ifdef AXI_BUSY
assign o_arready = (r_cs==ST_R_IDLE) & (axi_wait_cnt_0==axi_wait_num_0);
`else
assign o_arready = (r_cs==ST_R_IDLE);
`endifassign o_rresp = 2'b00;
assign o_rvalid = (r_cs==ST_R_READ);
assign o_rlast = o_rvalid & (rdcnt==arlen);
assign o_rid = arid;always@(posedge clk or negedge rstn) beginif (!rstn) beginr_cs <= ST_R_IDLE;end else beginr_cs <= r_ns;end
endalways@(*) beginr_ns = r_cs;case (r_cs)ST_R_IDLE : r_ns = (i_arvalid & o_arready) ? ST_R_PRE1 : r_cs;ST_R_PRE1 : r_ns = ST_R_PRE2;ST_R_PRE2 : r_ns = ST_R_PRE3;ST_R_PRE3 : r_ns = ST_R_READ;ST_R_READ : r_ns = (o_rvalid & i_rready & rdcnt==arlen) ? ST_R_END : r_cs;ST_R_END : r_ns = ST_R_IDLE;endcase
endalways@(posedge clk or negedge rstn) beginif (!rstn) beginrdcnt <= 4'd0;end else if (o_rvalid & i_rready) beginif (rdcnt==arlen) beginrdcnt <= 4'd0;end else beginrdcnt <= rdcnt + 1'b1;endend
endalways@(posedge clk) beginif (i_arvalid & o_arready) beginaraddr <= i_araddr;arlen <= i_arlen;arid <= i_arid;end
endalways@(posedge clk) beginif ((r_cs==ST_R_PRE3) || (r_cs==ST_R_READ)) begin$mem_read(araddr,o_rdata);araddr <= araddr + 4;end
end//------------------------------------------------------------------------------------------------
always@(posedge clk or negedge rstn) beginif (!rstn) beginw_cs <= ST_W_IDLE;end else beginw_cs <= w_ns;end
endalways@(*) beginw_ns = w_cs;case (w_cs)ST_W_IDLE : w_ns = (i_awvalid & o_awready) ? ST_W_PRE1 : w_cs;ST_W_PRE1 : w_ns = ST_W_PRE2;ST_W_PRE2 : w_ns = ST_W_PRE3;ST_W_PRE3 : w_ns = ST_W_WRITE;ST_W_WRITE : w_ns = (i_wvalid & o_wready & wdcnt==awlen) ? ST_W_END : w_cs;ST_W_END : w_ns = (o_bvalid & i_bready) ? ST_W_IDLE : w_cs;endcase
endalways@(posedge clk or negedge rstn) beginif (!rstn) beginwdcnt <= 4'd0;end else if (i_wvalid & o_wready) beginif (wdcnt==awlen) beginwdcnt <= 4'd0;end else beginwdcnt <= wdcnt + 1'b1;endend
endalways@(posedge clk) beginif (i_awvalid & o_awready) beginawaddr <= i_awaddr;awlen <= i_awlen;;awid <= i_awid;end
endalways@(posedge clk) begininteger t;if (i_wvalid & o_wready) begin$mem_write(awaddr,i_wstrb,i_wdata);awaddr <= awaddr + 4;end
end// for error checking
always@(posedge clk) beginif (i_wvalid & o_wready) beginif (wdcnt==awlen & !i_wlast) begin$display("[FAIL]: awlen does not match with wlast");$finish;endif (wdcnt!=awlen & i_wlast) begin$display("[FAIL]: awlen does not match with wlast");$finish;endend
end`ifdef AXI_BUSY
assign o_awready = (w_cs==ST_W_IDLE) & (axi_wait_cnt_1==axi_wait_num_1);
`else
assign o_awready = (w_cs==ST_W_IDLE);
`endifassign o_wready = (w_cs==ST_W_WRITE);
assign o_bresp = 2'b00;
assign o_bid = awid;
assign o_bvalid = (w_cs==ST_W_END);endmodule
verilog源码积累:ram和axi slaver相关推荐
- FPGA学习之路—接口(3)—SPI详解及Verilog源码分析
FPGA学习之路--SPI详解及Verilog源码分析 概述 SPI = Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线. 优点 支持全 ...
- FPGA学习之路—接口(2)—I2C协议详解+Verilog源码分析
FPGA学习之路--I2C协议详解+Verilog源码分析 定义 I2C Bus(Inter-Integrated Circuit Bus) 最早是由Philips半导体(现被NXP收购)开发的两线时 ...
- 三星uboot1.1.6源码分析——start.s(4)——从NAND复制源码到RAM(3)
通过上两篇博客终于把从NAND复制源码到RAM的c语言写的部分说完了,现在回到start.s中,接着分析余下的代码. ----------------------------------------- ...
- FPGA实现和ET1100通信verilog源码。 ethercat从站方案
FPGA实现和ET1100通信verilog源码. ethercat从站方案. YYID:34299659977307299
- FPGA实现和ET1100通信verilog源码。 ethercat从站方案。
FPGA实现和ET1100通信verilog源码. ethercat从站方案. 摘 要: EtherCAT是工业控制领域广泛应用的现场总线之一,从站控制器ESC(EtherCAT Slave Cont ...
- CORDIC算法计算复数相位角(含verilog源码)
前言 截止2022年2月15日,中国科学院大学<高等数字集成电路分析及设计>课程终于完结,所以我计划分享几个自己完成的实践作业,供大家交流学习. 设计收获 对cordic算法有了清晰的 ...
- 详解FPGA实现8b10b编码原理(含VHDL及verilog源码)
首发自https://hifpga.com/%E9%97%AE%E9%A2%98/37599 为什么要推出8b/10b编码? 8b/10b最常见的是应用于光纤通讯和LVDS信号的.由于光模块光模块只能 ...
- CRC-16/XMODEM串行计算的Verilog源码及仿真
文章目录 前言 一.CRC是什么? 二.硬件串行计算原理分析 1. 串行计算原理分析 (1) 原理图 (2) 计算过程 (3) 以CRC-16/XMODEM为例 2. Verilog代码 3. 仿真结 ...
- 8位伪随机序列(m序列verilog HDL源码 )
伪随机码又称伪随机序列,它是具有类似于随机序列基本特性的确定序列.通常广泛应用二进制序列,因此我们仅限于研究二进制序列.二进制独立随机序列在概率论中一般称为贝努利(Bernoulli)序列,它由 ...
- 74ls390设计任意进制计数器_异步FIFO:设计原理及Verliog源码
1. 异步FIFO的概念 异步FIFO为读取与写入采用不同的时钟,使用异步FIFO用于在不同的时钟域传输数据,主要用于跨时钟域传输多bit数据. 2. 异步FIFO的设计难点 同步异步信号,避免亚 ...
最新文章
- SSH-KeyGen 的用法 【转载】
- linux查看java jdk安装路径和设置环境变量
- 网页编程中的模态对话框
- HDU 1874 SPFA算法Dijkstra算法
- 在linux上一行代码不用写实现自动采集+hadoop分词
- Fiori My Task App Performance Analysis
- ACM - 第6章 数据结构基础(2)
- c# https请求
- Qt 中static_cast 和 reinterpret_cast的区别
- CS188-Project 4
- 【CG物理模拟系列】流体模拟--粒子法之MPS法(理论)
- 2021年美容师(初级)报名考试及美容师(初级)最新解析
- 一名软件测试工程师的一天24小时(每天在忙什么)
- MAC软件推荐(Java方向)
- aspose.words 操作 word 文档-文字替换、删除首行、添加水印等方案
- ThinkPad平板电脑在定价上还存在的一个问题是
- Chrome开发者工具详解(六)之Timeline面板
- 记一次fastadmin图片上传大小受限制的修改
- 数据库第一天 TAT
- 单枪匹马想要搞定亿级流量?2021阿里都换成这个牛逼架构了