hreadyout和hready_in的区别

AHB协议中slave的HREADYOUT和HREADYIN的区别

  • HREADYOUT:用于指示slave准备好接收master发过来的一笔传输
  • HREADYIN:用于指示slave的上一笔传输是否结束
    在这里插入图片描述

1. 没有hready_in会发生什么

由于AHB是支持pipeline传输的,所以当前的cycle会是上一个slave的data phase,也是下一个slave的addr phase。上面这张时序图表明master有两笔写传输,第一笔传输为slave1(s1),传输类型为SEQ,在第一笔传输的第二个周期,也就是第一笔传输的data phase,此时slave1没有准备好被写数据,因此把s1_hreadyout拉低,但此时slave2已经看到自己的NONSEQ传输了,而且slave2已经是准备好了的。如上图所示:

那这时master那边只能看到一个hready,那到底是看s1的还是s2的呢?

  • 如果看s1的话,那么master会在下一个周期维持NONSEQ,那么s2会认为,我已经在上一个周期接收了一个NONSEQ,现在又来了一个NONSEQ并且addr还没有递增。在s2会发生protocol fail。如下图1所示:
  • 如果看s2的话,那么s1的写数据就会失败,因为当前s1还没有准备好。如下图2所示:
    在这里插入图片描述

在这里插入图片描述

2.有hready_in会发生什么

那么这个时候就要引入我们的hready_in了。这个hready_in有两种写法:

  • 通过一个mux,把在data phase的slave的hreadyout作为输入连接到所有的slave
  • 把所有的slave的hreadyout相与,然后再连接到所有的slave

在这里插入图片描述

slave必须看到自己的hreadyin&hreadyout,才认为一次addr phase/data phase的成功。

而且slave必须等到hreadyin为高电平时才进行addr以及控制信号的采样:

if(hreadyin) 
begin
	addr_reg <= haddr;
	htrans_reg <= htrans;
	hwrite_reg <= hwrite;
end

在这里插入图片描述
重新拿上面的仿真图看一下,由于前一个周期的s1_hreadyout为低电平,所以s2的hready_in也为低电平,那么该周期s2不会对addr以及控制信号进行采样。在下一个周期s1以及准备好了,s1_hreadyout拉为高电平,s2的hready_in也为高电平,表示上一笔传输以及结束了,可以开始下一笔传输,也就是s2的传输,此时s2就可以对addr以及控制信号进行采样了。就不会出现上面的问题。

  • 37
    点赞
  • 163
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
#include<stdio.h> #include "dos.h" #include "stdlib.h" #include "conio.h" //PCB结构体 struct pcb{ int id; //进程序号 int ra; //所需资源A的数量 int rb; //所需资源B的数量 int rc; //所需资源C的数量 int ntime; //所需的时间片个数 int rtime; //已经运行的时间片个数 char state; //进程状态 struct pcb *next; } *hready=NULL,*hblock=NULL,*p; //hready,hblock分别为指向就绪和阻塞队列 typedef struct pcb PCB; int m,n,r,a,b,c,h=0,i=1,time1Inteval; //m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //建立一个PCB结构体型的空链表 PCB *increat(void) { PCB *head=NULL; //head=NULL; return(head); } //从链表起始地址开始输出该链表的内容 void disp(PCB *head) {PCB *p1; p1=head; AnsiString str2; if(head!=NULL) //链表非空 { do { str2+=" "; str2+=IntToStr(p1->id);str2+=" "; str2+=(p1->state);str2+=" "; str2+=IntToStr(p1->ra);str2+=" "; str2+=IntToStr(p1->rb);str2+=" "; str2+=IntToStr(p1->rc);str2+=" "; str2+=IntToStr(p1->ntime);str2+=" "; str2+=IntToStr(p1->rtime);str2+="\r\n"; p1=p1->next; }while(p1!=NULL); //不断输出进程的信息,直到链尾! } //if else { str2+="\t\t该 队 列 中 没 有 进 程!\r\n" ;} Form1->Memo1->Lines->Add(str2); } //将进程插入到链尾(包括就绪队列和阻塞队列) PCB *insert(PCB *head,PCB*pcb) //带两个指针形参:队列指针和当前进程PCB { PCB *pi,*p1; p1=head; pi=pcb; if (head==NULL) { head=pi; pi->next=NULL; } else { while(p1->next!=NULL) {p1=p1->next;} p1->next=pi; pi->next=NULL; } return(head); } //对进程进行初始化,建立就绪队阻塞队列。 void input() { AnsiString str1; m=StrToInt (Form1->Edit1->Text); //读取要模拟的进程总数给m n=StrToInt (Form1->Edit2->Text); //读取需初
实验一 进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序 。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法 的具体实施办法。 二、实验内容及要求 1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进 程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据 实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行 时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均 由用户给定。 2、系统资源(r1…rw),共有w类,每类数目为r1…rw。随 机产生n进程Pi(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程 中,会随机申请新的资源。 3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设 初始状态为就绪状态。建立进程就绪队列。 4、编制进程调度算法:时间片轮转调度算法 本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需 要的时间片数减1。在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执 行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1 ,并排列到就绪队列的尾上。 三、实验环境 操作系统环境:Windows系统。 编程语言:C#。 四、实验思路和设计 1、程序流程图 2、主要程序代码 //PCB结构体 struct pcb { public int id; //进程ID public int ra; //所需资源A的数量 public int rb; //所需资源B的数量 public int rc; //所需资源C的数量 public int ntime; //所需的时间片个数 public int rtime; //已经运行的时间片个数 public char state; //进程状态,W(等待)、R(运行)、B(阻塞) //public int next; } ArrayList hready = new ArrayList(); ArrayList hblock = new ArrayList(); Random random = new Random(); //ArrayList p = new ArrayList(); int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //对进程进行初始化,建立就绪数组、阻塞数组。 public void input()//对进程进行初始化,建立就绪队列、阻塞队列 { m = int.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0; listBox1.Items.Add("产生进程ID:" + jincheng.id); listBox1.Items.Add("所需A资源数目:" + jincheng.ra); listBox1.Items.Add("所需B资源数目:" + jincheng.rb); listBox1.Items.Add("所需C资源数目:" + jincheng.rc); listBox1.Items.Add("所需时间片数:" + jinc
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明
作为AI语言模型,我无法编写代码,但是我可以提供一个简单的AHB驱动器的伪代码示例,帮助您了解AHB驱动器的工作原理。 ``` module AHB_Driver ( input [31:0] AHB_Address, input [31:0] AHB_Data_In, input AHB_Write, input AHB_Read, input AHB_HCLK, input AHB_HRESETn, output [31:0] AHB_Data_Out, output AHB_HREADY, output AHB_HRESP ); // 内部寄存器 reg [31:0] internal_data; // AHB状态机状态定义 localparam IDLE = 0, READ = 1, WRITE = 2; // AHB状态机变量 reg [1:0] state; reg [31:0] read_address; // AHB状态机主体 always @(posedge AHB_HCLK or negedge AHB_HRESETn) begin if (!AHB_HRESETn) begin state <= IDLE; internal_data <= 0; read_address <= 0; AHB_Data_Out <= 0; AHB_HREADY <= 1; AHB_HRESP <= 0; end else begin case (state) IDLE: begin if (AHB_Read && AHB_Write) begin AHB_HRESP <= 2'b10; // 错误响应 end else if (AHB_Read) begin read_address <= AHB_Address; state <= READ; end else if (AHB_Write) begin internal_data <= AHB_Data_In; state <= WRITE; end else begin AHB_HRESP <= 2'b00; // 正确响应 end end READ: begin AHB_HREADY <= 0; if (AHB_HREADY && !AHB_HRESP) begin AHB_Data_Out <= internal_data; state <= IDLE; end end WRITE: begin AHB_HREADY <= 0; if (AHB_HREADY && !AHB_HRESP) begin state <= IDLE; end end default: begin AHB_HRESP <= 2'b10; // 错误响应 end endcase end end endmodule ``` 这是一个简单的AHB驱动器模块,可以实现单个AHB总线事务的读取和写入。该驱动器包含一个状态机,用于在AHB总线上实现读取和写入操作。在读取操作中,驱动器将读取地址保存在一个寄存器中,并在AHB_HREADY信号变为高电平时将内部数据写入AHB_Data_Out。在写入操作中,驱动器将输入数据保存在另一个寄存器中,并在AHB_HREADY信号变为高电平时将状态返回到空闲状态。如果在操作期间发生错误,则将AHB_HRESP设置为2'b10,表示错误响应。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值