Menu Close

RISC-V PLIC设计(1) CPU设计

1.中断源(ID)定义

 

相关参考文章:

RISC-V教学教案

 

在地址图(详细内容点击这里)上对中断源的定义如图1所示。可以看到,目前地址图V1.2定义了63个中断源(中断源0为没有中断)。

interrupt_id

图1 中断源(ID)

 

中断源在CPU内部的实现如下所示,其中具体的外部中断请求都会连接到各自的模块输出。例如:pwm3_cmp_irq(pwm3比较结果的中断请求)是PWM模块中的输出。而汇集了所有类型的中断源i_plic_irq将会被输入到外部平台级中断处理(PLIC)内核,进行仲裁,选举出将要处理的中断请求。即当同时有多个外部中断请求产生时,PLIC内核只会允许发生一个中断。

 

wire i2c3_irq;
wire i2c2_irq;
wire i2c1_irq;
wire i2c0_irq;
wire [3:0] pwm3_cmp_irq;
wire [3:0] pwm2_cmp_irq;
wire [3:0] pwm1_cmp_irq;
wire [3:0] pwm0_cmp_irq ;
wire spi3_irq;
wire spi2_irq;
wire spi1_irq;
wire spi0_irq;

wire [31:0] o_GPIO_irq;

wire uart3_irq;
wire uart2_irq;
wire uart1_irq;
wire uart0_irq;
wire rtc_cmp1_irq;
wire rtc_cmp0_irq;
wire watchdog_irq;

//注意这里的外部中断源排列是由高到低
wire [PLIC_IRQ_NUM - 1:0] i_plic_irq = {
i2c3_irq,
i2c2_irq,
i2c1_irq,
i2c0_irq,
pwm3_cmp_irq[3:0], //56-59
pwm2_cmp_irq[3:0], //52-55
pwm1_cmp_irq[3:0], //48-51
pwm0_cmp_irq[3:0], //44-47
spi3_irq,
spi2_irq,
spi1_irq,
spi0_irq,
o_GPIO_irq[31:0], // 8-39
uart3_irq,
uart2_irq,
uart1_irq,
uart0_irq,
rtc_cmp1_irq,
rtc_cmp0_irq,
watchdog_irq,
1'b0  //注意中断源0表示没有中断
};

 

 

2.中断源关口(gateway)定义

每个中断源都有一个关口,主要处理中断信号并将其发送到PLIC内核,内核将这些中断信号锁存在中断悬挂位中。每个中断源都有单独的优先级。当目标中断源使能被拉高,且优先级大于阈值,则PLIC内核会向目标发送中断通知。目标接收到外部中断后,向内核发送一个中断声明,请求检索有最高优先级的悬挂中断,并清除相应的中断悬挂位。在中断完成后,目标向关口发送完成信息。

每个中断源只能在PLIC内核悬挂一个中断请求。关口仅在收到来自同源的先前的中断处理程序的通知已完成后,才将新的中断请求转发到PLIC内核。

图2所示为PLIC对中断处理的流程。可以看到,gateway一次仅将一个中断请求转发给PLIC,直到接收到中断完成后才转发后续的中断请求。目标可能需要一段时间来响应新的中断到达,但随后将向PLIC内核发送中断请求以获取中断ID。 PLIC内核将自动返回ID并清除相应的IP位,此后,其他任何目标都无法声明相同的中断请求。 处理程序处理完中断后,它将向gateway发送中断完成消息,以允许新的中断请求。

plic_gateway

图2 PLIC 中断处理流程 [1]

 

相应的PLIC gateway代码(只显示相关部分)如下:

// 为每个中断源实现关口

IRQ_gateway IRQ_gateway_inst (
.clk ( clk ),                                       //时钟
.rst_n ( rst_n ),                                   //复位
.i_interrupt ( plic_irq_i_r ),                   //中断源
.o_plic_valid ( irq_i_gated_valid ),             //输出中断是否有效通过关口
.i_plic_read ( irq_i_gated_ready ),              //cpu 读
.i_plic_write ( rib_complete_irq )               //cpu 写
);

assign irq_i_gated_hsked = irq_i_gated_valid & irq_i_gated_ready;//定义关口握手信号,由中断有效通过关口信号 & CPU读信号决定


//gateway模块
module IRQ_gateway
(
input clk,                                          //时钟

input i_interrupt,                                 //中断源
output o_plic_valid,                               //输出中断是否有效通过关口
input i_plic_read,                                 //cpu 读
input i_plic_write,                                //cpu 写

input rst_n                                        //复位
);

reg inFlight;

assign o_plic_valid = (inFlight == 1'h0) ? i_interrupt : 1'b0;   //如果inFlight为0,且有中断源到来,输出中断有效,否则输出中断无效
wire int_valid = i_interrupt & i_plic_read;                      //cpu读 & 中断源到来

always @(posedge clk or negedge rst_n) 
if (!rst_n) 
begin
inFlight <= 1'h0;
end 
else 
begin
if (i_plic_write)               //如果cpu写入,inFlight为0
inFlight <= 1'h0;
else if (int_valid)             //cpu读 & 中断源到来,inFlight为1
inFlight <= 1'h1;
end

endmodule

 

3.中断仲裁

比较和选择悬挂中断的部分代码如图3所示。一共有10层比较数组。其实现的逻辑是将每层数组相邻的数两两比较,给出其中较大的数,并放入下一层数组,直到得到最大的数。因为sifive公司定义了1024个中断源,为了与此兼容,FII RISC-V CPU用于中断仲裁的模块也是最大可以容纳1024个中断源(实际为1023个,因为中断源0表示没有中断发生),那么每经过一层数组比较,下一层数组就缩减了一倍。因为log(2)1024 = 10,所以这里用了10层比较数组来选举出优先级最高的中断源。

arbitrition

图3 仲裁代码

 

图4是一个3层比较数组的例子,方格中的数字指的是数组的索引。可以通过图4来理解图3中代码的数组索引运用。

比较结构

图4 比较结构

 

图5所示是将数字1-8随机放进数组索引0-7的举例。可以看到经过每层比较后,最终剩下的是1-8中最大的数,8。

图5 仲裁举例

 

 

4.中断悬挂(部分)

相关代码如下:

// 为每个中断源实现中断悬挂位

// 如果清除了挂起的中断源,则可以接受来自关口的新中断
assign irq_i_gated_ready = (~irq_pend_r);

// 当关口输出握手信号,中断源悬挂被立起来
assign irq_pend_set = irq_i_gated_hsked;



//声明了最高优先级的悬挂中断后,相应的中断悬挂被清除

assign irq_pend_clr = rib_claim_irq;                                // 如果中断被声明,清除相应的中断源悬挂                                                                 
assign irq_pend_ena = (irq_pend_set | irq_pend_clr);             //使能由中断悬挂设立信号或是悬挂清除信号立起来
assign irq_pend_nxt = (irq_pend_set | (~irq_pend_clr));          //输入d flip flop的悬挂信号

fii_dfflr #(1) irq_pend_dfflr(irq_pend_ena , irq_pend_nxt, irq_pend_r, clk, rst_n);              //锁存

 

 

5.文章参考

[1] Www2.eecs.berkeley.edu, 2021. [Online]. Available: https://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/EECS-2016-129.pdf. [Accessed: 29- Mar- 2021].

Posted in RISC-V, RISC-V 外设, RISC-V 教材教案, RISC-V开发板, 应用开发, 开发板, 教材与教案, 文章

发表评论

您的电子邮箱地址不会被公开。

Leave the field below empty!

相关链接