当前位置: 首页 > news >正文

AHB总线读写RAM

`timescale 1ns/1ps

module ahb2ram #(parameter ADDR_BITS = 32) (
input resetn,
input ahb_clock,
input [1:0] ahb_htrans,//传输类型00:idle, 01:busy, 10:NONSEQ, 11:SEQ NONSEQ:新数据 SEQ:连续传输 IDLE:空闲 BUSY:忙
input [2:0] ahb_hsize,
input [31:0] ahb_hwdata,
input [31:0] ahb_haddr,
input ahb_hwrite,
output reg [31:0] ahb_hrdata,
output reg ahb_hreadyout,
output [ADDR_BITS-3:0] ram_addr,
output reg [3:0] ram_byteena,
output [31:0] ram_data,
output reg ram_wren,
output ram_rden,
input [31:0] ram_q
);
// All AHB signals assume 1 cycle latency from RAM (no output register)
//写时序说明
//1. 在 T0 上升沿:
// - 主机驱动地址 HADDR
// - 设置 HTRANS = NONSEQ
// - 设置 HWRITE = 1
// - 从机在该上升沿采样地址与控制信号
//
//2. 在 T1 上升沿:
// - 主机驱动写数据 HWDATA
// - 从机在 HREADY=1 的情况下采样 HWDATA
// - 若 HREADY=0,主机必须保持所有信号不变
//
//3. 若 HREADY=0:
// - 主机在后续每个时钟周期保持
// HADDR / HTRANS / HWRITE / HWDATA
// - 直到从机拉高 HREADY
// - 在 HREADY=1 的上升沿,写数据被正式采样

reg [ADDR_BITS-1:0] haddr_reg;
reg [2:0] hsize_reg;
reg [31:0] ram_qd;
reg rd_en_d1;//打拍
reg rd_en_d2;//采样ram_q
reg rd_en_d3;//驱动HRDATA
//AHB读数据 NONSEQ / SEQ
//在AHB读操作中,RAM 具有1拍读延迟,而从机必须在 HREADY=1 的那一拍提供有效的 HRDATA;
//因此需要在读开始时拉低 ahb_hreadyout,插入一拍等待,使 RAM 读数据与 AHB 数据阶段对齐
wire rd_en = !ahb_hwrite && (ahb_htrans[1] || !ahb_hreadyout);

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn) begin
ram_byteena <= 4’b1111;
end else if (ahb_htrans[1] && ahb_hwrite) begin
if (ahb_hsize == 3’b000) begin // byte write
case(ahb_haddr[1:0])
2’b00: ram_byteena <= 4’b0001;
2’b01: ram_byteena <= 4’b0010;
2’b10: ram_byteena <= 4’b0100;
2’b11: ram_byteena <= 4’b1000;
default: ram_byteena <= 4’hX;
endcase
end else if (ahb_hsize == 3’b001) begin // halfword write
case (ahb_haddr[1])
1’b0: ram_byteena <= 4’b0011;
1’b1: ram_byteena <= 4’b1100;
default:ram_byteena <= 4’hX;
endcase
end else begin // word (including above) write
ram_byteena <= 4’b1111;
end
end
end

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn) begin
hsize_reg <= 3’b0;
end else if (ahb_htrans[1]) begin
hsize_reg <= ahb_hsize;
end
end

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn)
ram_wren <= 0;
else if (ahb_htrans[1] && ahb_hwrite)
ram_wren <= 1;
else
ram_wren <= 0;
end

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn)
haddr_reg <= 0;
else if (ahb_htrans[1] & ahb_hwrite && ahb_hreadyout)
haddr_reg <= ahb_haddr[ADDR_BITS-1:0];
else if (ahb_htrans == 2’b10 && !ahb_hwrite && ahb_hreadyout)
haddr_reg <= ahb_haddr[ADDR_BITS-1:0];
else if (ahb_htrans == 2’b11 && !ahb_hwrite && rd_en_d1)
haddr_reg <= haddr_reg + (1 << hsize_reg);
end

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn) begin
rd_en_d1 <= 0;
rd_en_d2 <= 0;
rd_en_d3 <= 0;
end else begin
rd_en_d1 <= rd_en;
rd_en_d2 <= rd_en_d1;
rd_en_d3 <= rd_en_d2;
end
end

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn)
ahb_hreadyout <= 1;
else if (rd_en && !rd_en_d1)//第一个上升沿
ahb_hreadyout <= 0;
else if (rd_en_d3 && rd_en_d2)//
ahb_hreadyout <= 1;
end

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn)
ahb_hrdata <= 0;
else if (rd_en_d3)
ahb_hrdata <= ram_qd;
end

always @ (posedge ahb_clock or negedge resetn) begin
if (!resetn)
ram_qd <= 0;
else if (rd_en_d2)
ram_qd <= ram_q;
end

assign ram_addr = haddr_reg[ADDR_BITS-1:2];
assign ram_data = ahb_hwdata;
assign ram_rden = rd_en_d1;

endmodule

http://www.jsqmd.com/news/521860/

相关文章:

  • LibreCAD编译进阶:如何优化Qt Creator配置提升编译效率(附性能对比测试)
  • AI破界:2026消费创新爆发:AI助手一句话下单1.2亿次背后的商业变局
  • 超越CBAM与ECA:YOLOv8引入Shuffle Attention(SA)机制,实现轻量级高效注意力
  • 明文注入隐忧:CVE-2026-1642漏洞深度解析,NGINX全球部署安全预警
  • TwinCAT3 YT Scope Project实战:如何用倍福工具实现工业自动化数据可视化(附多曲线叠加技巧)
  • Uibot实战:自动抓取校内期刊分级列表,科研党必备的文献查询自动化工具
  • 开源 AI 助手 OpenClaw 2026.2.23 发布:安全更新与 AI 能力双轮驱动升级
  • 基于蚂蚁-遗传优化算法的路径规划问题(Matlab代码实现)
  • 在CentOS 7上给KVM虚拟机直通N卡跑AI:从硬件检查到避坑实战
  • 深度解析AlienFX Tools:开源Alienware硬件控制终极解决方案
  • 别再只会用BotFather了!用Python-telegram-bot库给你的Telegram机器人加个‘天气查询’功能(附完整代码)
  • RTMP vs. HTTP-FLV:直播协议选型指南与性能对比
  • Qwen3-ASR-0.6B模型部署到STM32:嵌入式语音识别实战
  • 从零开始玩转ROS的rqt工具:手把手教你配置与使用
  • numpy-docs-l10n
  • ClearerVoice-Studio商业应用:短视频配音净化+采访音频精准提取
  • 调试 vs
  • Havenask开源首年踩坑记:从零部署到性能调优的7个关键步骤
  • 大数据基于Python的事业单位报考数据分析与可视化
  • ai(四) 分类
  • AI投研范式革新:OpenClaw赋能金融投研的17个实战案例与未来展望
  • GEM嵌入式菜单库:轻量级多级HMI开发实战指南
  • 南北阁Nanbeige 4.1-3B实战:利用卷积神经网络(CNN)原理优化图像理解Prompt
  • nanobot入门指南:超轻量OpenClaw镜像部署Qwen3-4B并验证llm.log日志
  • 系统集成项目管理工程师证书的含金量解析:职业发展与薪资提升
  • 实战指南:如何利用CVE-2017-0146(永恒之蓝)在内网中横向移动
  • Qwen2-VL-2B-Instruct创意应用:AI辅助生成短视频分镜脚本与画面描述
  • 碎片化时间利用程序,识别等车排队空档,推荐微学习,积少成多,提升自己。
  • 为什么你的STM32 printf不工作?深入解析串口重定向与标准库的恩怨情仇
  • 常见问题:bge-large-zh-v1.5启动失败怎么办?手把手解决