项目:AHB接口的特定传输操作MASTER模块

AHB接口的特定传输操作MASTER模块

//题目:AHB接口的模拟MASTER模块
//设计内容:
//针对给定的AMBA AHB SRAM Slave接口模块,设计特定传输操作的Master模块
//设计指标:
//AMBA AHB2.0 接口
//32bit 数据位宽
//先写入数据,后读出数据确认
//传输要求1:0x0 ‐> 0x8, INCR
//传输要求2:0x10‐> ?, INCR4
//传输要求2:0x28‐> ?, WRAP8
//实验内容:
//完成RTL设计
//完成TESTBENCH设计
//完成设计验证文档

目录
我的源码链接
1.介绍AMBA2.0总线
总线设备
总线的信号
总线传输的两个阶段
2. 设计思路解析
读写数据的赋值规则
位地址控制
3.代码问题分析


注:部分代码来自于https://mp.weixin.qq.com/s/P4jevRrkga2DF93UPXLUJg
说明:
1 如果你想使用或在我的代码基础上debug,可到我主页下载https://download.csdn.net/download/qq_43029779/85274862?spm=1001.2014.3001.5503
代码部分综述:
ahb_top.v是连接ahb_master, ahb2sram, fpga_sram的顶层设计文件
ahb_top_tb.v是整个工程的testbench
Master.v是借鉴网上代码所写,仍有许多问题,,
如地址没能确定完全读入至SRAM内之后再自增,1kb边界trans发noseq的问题
Master.v分为数据传输部分,地址控制部分,trans数据转换状态机.

2 同时,另一份AHB_master代码,通过脑动写入数据和地址模拟完成ahbmaster操作也可在我主页下载https://download.csdn.net/download/qq_43029779/85274937?spm=1001.2014.3001.5503
3 代码仅用于学习交流使用


1.介绍AMBA2.0总线
典型的soc结构如下
在这里插入图片描述
高速总线ahb通过apb_bridge连接带apb接口的slave。
在这里插入图片描述
多个master通过arbiter仲裁器仲裁主机并传输地址和数据,slave通过decoder译码器来向主机传输信息。
总线设备
1.1 AHB 主设备(master)
 初始化一次读/写操作
 某一时刻只允许一个主设备使用总线
 uP、DMA、DSP、LCDC …
1.2 AHB从设备(slave)
 响应一次读/写操作
 外部存储器控制器EMI、APB bridge、UART、 …
1.3 AHB仲裁器(arbiter)
 允许某一个主设备控制总线
 在AMBA协议中没有定义仲裁算法
1.4 AHB译码器(decoder)
 通过地址译码来决定选择哪一个从设备
总线的信号
总线的信号
Hclk是主机发出的时钟;hresetn是主机发出的复位信号;haddr32位地址线;
htrans传输的状态:NONSEQ、SEQ、IDLE、BUSY
hwrite 写使能信号,1写,0读
hsize传输的数据位宽:8、16、32
hburst传输的burst类型,single、incr4/8/16、wrap4/8/16
//代码部分会详细介绍如何计算incr以及wrap
hprot保护控制信号;hwdata32位写数据信号;hselx选择从机信号
hrdata32位读数据信号,hready由从机发出给主机,告诉主机 从机是否准备好 高:从设备指出传输结束/ 低:从设备需延长传输周期
hresp是从机发出的状态,表示他对主机的应答情况OKAY、ERROR、RETRY、SPLIT
总线传输的两个阶段
 地址周期(地址和控制信号),只有一个cycle
 数据周期(读数据/写数据),由HREADY信号决定
需要几个cycle
 流水线传送
 先是地址周期,然后是数据周期
master端口描述
从设备端口
2. 设计思路解析
项目已经给我们了sram, apb转接module,要求是设计一个ahb_master,即我们需要通过模拟建立一个主机,通过apb接口向从机sram发送控制信号,最后通过top文件将三个module连接。
首先设计端口如下

在这里插入代码片
module AHB_master(
					//---------- 输入:系统信号 ----------
					//	HGRANTx,//指出主设备x可访问总线(ARBITER发出)- 主设备x控制总线:HGRANTx=1且HREADY=1
						HCLK,
						HRESETn,//systenm signal
						
					//-------- 输入 响应信号:s->M -----------------
						HRESP,//从设备发给主设备的总线传输状态 OKEY、ERROR、RETRY、SPLIT		
						HREADYOUT,//高:从设备指出传输结束 - 低:从设备需延长传输周期		
					//-------- 输入 :地址和控制信号-----------------
						in_ADDR,
						in_TRANS,
						in_WRITE,
						in_SIZE,
						in_BURST,
					//---------- 输入:读数据信号 --------------	
						HRDATA,//读数据总线,从从设备读到主设备
					//-------- 输出:地址和控制信号----------------
						HADDR,//32位系统地址总线
						HTRANS,//传输的状态:00;IDLE、01;BUSY、10;NONSEQ、11;SEQ
						HWRITE,
						HSIZE,//传输的数据位宽:8、16、32
						HBURST,//传输的burst类型,single、incr4/8/16、wrap4/8/16
					//	HPROT,
						
					//---------- 输出:写数据信号 --------------	
						HWDATA//写数据总线,从主设备写到从设备
					//	HSELx,//指明当前传输被访问的从设备,来自译码器
						);

然后定义各信号的参数

在这里插入代码片
// ------------- 定义参数 ----------------------

//传输类型:HTRANS
parameter SRAM_IDLE=00;
parameter SRAM_BUSY=01;
parameter SRAM_NOSEQ=10;
parameter SRAM_SEQ=11;

//传输的burst类型 
parameter single	=	000;
parameter incr 	=	001;
parameter wrap4 	=	010;
parameter incr4 	=	011;
parameter wrap8 	=	100;
parameter incr8 	=	101;
parameter wrap16 	=	110;
parameter incr16 	=	111;
//从设备发给主设备的总线传输状态:HRESP
parameter OKAY  =	00;
parameter ERROR =	01;
parameter RETRY =	10;
parameter SPLIT =	11;

//传输的 Hsize 类型 
parameter size_1 		=	000;
parameter size_2 		=	001;
parameter size_4 		=	010;
parameter size_8 		=	011;
parameter size_16 	=	100;
parameter size_32 	=	101;
parameter size_64 	=	110;
parameter size_128 	=	111;

parameter state_idle = 0,  state_write = 1, state_read = 2;

下面这一段是读写数据的赋值规则
1.如果是读操作就就把接收到的数据给rec_data
2.如果不复位就开启burst传输的方式,并选择传输字节数,其中,如果是写操作&从机不忙 就把数据写入data
否则保持数据。

在这里插入代码片

always @ (negedge H_clk)begin
if(!i_WR && !busy)
  rec_data <= R_data;
end
always @ (posedge H_clk , negedge H_rstN)
  begin
    if (!H_rstN)
      begin    
        //WR     <= 1'b0; 
        size   <= 3'b0;
        burst  <= 4'b0;    
        data   <= 0;
        data_1 <= 0;
      end 
    else if (H_readyN)responce check
      begin      
        //WR     <= i_WR; 
        size   <= i_size;
        burst  <= i_burst; 
        if (i_WR && !busy)
          begin      //data is chnaging in busy so i need control here
            data_1 <= i_data;//one cycle late data 
            data   <= data_1;
          end
        else    
          data   <= data_1; //also make it xx
      end
    else  begin
        data_1 <= data_1; //one cycle late data 
        data   <= data;
      end
  end

以下一段位地址控制,如果从机状态是HTRANS_NONSEQ,那么就将add <= i_add,
地址i_add [12:0]给initial_add赋值,这里只取13位,2^12=8kb(这里设置initial_add的原因是后面要通过burst传输和hsize计算地址)
temp_counter 是计算burst传输次数的节拍器,每传输一次数据,节拍器就减一;
cal_size是hsize定义的字节长度
余下的类别就是single、incr4/8/16、wrap4/8/16
single最简单,直接传地址+数据;
incr也简单,直接地址=上一次地址+cal_size即可,但这里没有定义停止incr的问题,也没有注意跨越1kb边界问题。(下文分析了问题)
wrap的计算较为复杂,出去计算 地址以 hsize定义的字节长度 自增外,还要计算回环的首地址与回环的地址长度bound

在这里插入代码片
//address control  
always @ (posedge H_clk or negedge H_rstN)
begin
if (!H_rstN)                                                            
  begin add  <= 32'b0;WR<=0;end
else if (H_readyN && trans_next == HTRANS_NONSEQ)  //single 
  begin                 
    initial_add  <= i_add [12:0];  //13位,8kb,1kB
    add  <= i_add;
    WR<=i_WR; //single just sample
    temp_counter <= counter;// beats 
  end
  //&& trans_next == HTRANS_SEQ
else if(H_readyN &&(!busy)  && i_burst == INCR )  //check dependency on H_readyN and also restrict 1024KB size for future
    begin add  <= add + cal_size;//i_size determine cal_size
      WR<=i_WR;
    end
    
    //incr not define length,may cause 1KB problem
else if(H_readyN &&(!busy) && temp_counter != 0 && trans_next == HTRANS_SEQ //wrap burst
    && (i_burst == WRAP4 | i_burst == WRAP8 | i_burst == WRAP16 ))
  begin                 
    temp_counter <= temp_counter -1;//拍数减1
    if((add[12:0]+cal_size) >= wrap_bound)//超越边界,减去传输大小,spec
      add  <={add[31:13],((add[12:0]+ cal_size) - trans_size)};
    else
      add  <={add[31:13],(add[12:0] + cal_size)};//size
  end      
else if(H_readyN &&(!busy) && temp_counter != 0 && trans_next == HTRANS_SEQ 
    && (i_burst == INCR4 | i_burst == INCR8 | i_burst == INCR16 ))
  begin        
    add  <= (add + cal_size);  //size
    temp_counter <= temp_counter -1;
  end
else if ((i_burst == SINGLE)||(i_trans == HTRANS_IDLE)) 
  temp_counter <= 0;
else
  begin
    add <= add;
    temp_counter <= temp_counter;//maintain 
  end
end

1 先计算块传输的大小的trans_size ,再计算开始地址是块传输的倍数,
2 Start_add是块传输的理论的起始地址
3 Warpbound是warp的边界,若达到该地址则改从Start_add开始传输。
例如:计算hsize=8BYTE,burst=wrap8,则trans_size =8*8=64=2^6,起始地址应该是(当前地址除以64) 的整倍数(即该首地址是第几个block)再乘trans_size(即一个block的大小) 。

在这里插入代码片
//combination ADDRESS logic calculation
always @ (cal_burst,i_size,initial_add,shifty,cal_size)
begin 
  trans_size = cal_burst * cal_size;
  start_add  = ((initial_add >> shifty)*(trans_size)); //synthesis doesn't provide divide operator
  wrap_bound = start_add + trans_size ;
end

3.代码问题
功能1:burst= incr4
在起始地址0x22开始,输入四个数据12345678,88884444,44442222,22221111,
可以通过HRDATA读出数据流水线写入, 同时应该trans从开始发出noseq,seq,seq,seq,idle,但目前trans时序还不太正确。
在这里插入图片描述

功能2:burst= warp8
写入数据时,地址能够自动按照size和burst自增,但没能确定完全读入至SRAM内之后再自增。
数据读取正常,读出的数据正常,回环经历了覆盖历史数据。
在这里插入图片描述
在这里插入图片描述

功能3:incr
目前手地址无法写入,也没有解决1kb边界trans发noseq的问题,待后续修改。
在这里插入图片描述

代码部分综述:
ahb_top.v是连接ahb_master, ahb2sram, fpga_sram的顶层设计文件
ahb_top_tb.v是整个工程的testbench
Master.v是借鉴网上代码所写,仍有许多问题,,
如地址没能确定完全读入至SRAM内之后再自增,1kb边界trans发noseq的问题

Master.v分为数据传输部分,地址控制部分,trans数据转换状态机.
在这里插入图片描述

如果reset就赋初值,
如果是incr就地址逐增size
如果是wrap就计算bound值
在这里插入图片描述
上图代码表示先计算块传输的大小的bound,再计算开始地址是块传输的倍数,
Start_add是块传输的理论的起始地址
Warpbound是warp的边界,若达到该地址则改从Start_add开始传输。

trans数据转换状态机部分。

应增加:(来解决跨越1kb边界问题,即,trans发一个noseq,将块传输变为一个新的incr)
if(H_readyN &&(!busy) && trans_next == HTRANS_SEQ && i_burst == INCR &&(initial_add[9:0]+cal_size-1 ==9’h3ff) )begin
trans_next = HTRANS_NONSEQ;

另:更改了ahb_to_sram的地址问题:由于其中addr{1:0}用来作为判断字节通道的参数没有被后续加入HADD【13:0】里,但这样会导致地址不是16位,无法在SRAM中寻址,故,统一将地址改为16位,

另:sram中逻辑问题:判断RDATA=merge1?Sramdata:buffer,
会导致数据RDATA一直有值(即使在writen=1时),在这里改成了用always块判断!writen再赋值。

  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sr_shirui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值