SpinalHDL之杂项

本文作为SpinalHDL学习笔记第二十八篇,介绍SpinalHDL 使用小组件。

目录:

1.PLIC 映射器

2.插件

1.PLIC 映射器

PLIC 映射器定义了 PLIC(平台级中断控制器)的寄存器生成和访问。

PlicMapper.apply(bus: BusSlaveFactory, mapping: PlicMapping)(gateways : Seq[PlicGateway],targets : Seq[PlicTarget])

PlicMapper 的参数:

• bus:连接此控制器的总线

• mapping:一个映射配置(见上文)

• gateways:用于生成总线访问控制的 PlicGateway(中断源)序列

• targets:生成总线访问控制的 PlicTarget 序列(如:多核)

它遵循 riscv 提供的接口: https://github.com/riscv/riscv-plic-spec/blob/master/riscv-plic.adoc

截至目前,有两种内存映射可用:

PlicMapping.sifive

遵循 SiFive 的 PLIC 映射(例如 E31 核心复合手册 ),基本上是一个成熟的 PLIC

PlicMapping.light

此映射生成更轻量级的 PLIC,但代价是缺少一些可选特性:

• 不读取中断优先级

• 不读取中断的挂起位(必须使用声明 (claim)/完成 (complete) 机制)

• 不读取目标的阈值

剩下的寄存器 & 逻辑会被生成。

2.插件

对于某些设计,您可能希望通过使用某种插件来组合组件的硬件,而不是直接在组件中实现硬件。这可以提供一些关键特性:

• 可以通过在组件的参数中添加新的插件来扩展组件的功能。例如,在 CPU 中添加浮点支持。

• 可以通过使用另一组插件来轻松切换相同功能的各种实现。例如,某个 CPU 乘法器的实现可能在某些 FPGA 上表现良好,而其他实现可能在 ASIC 上表现良好。

• 它避免了非常非常庞大的手写顶层结构,其中一切都必须手动连接的情况。相反,插件可以通过查看/使用其他插件的软件接口来发现它们的关联关系。

VexRiscv 和 NaxRiscv 项目就是这方面的例子。它们是具有大部分是空白的顶层的 CPU,其硬件部分通过插件注入。例如:

• PcPlugin

• FetchPlugin

• DecoderPlugin

• RegFilePlugin

• IntAluPlugin

• …

这些插件将通过他们的服务池进行协调/传递/互连。

虽然 VexRiscv 使用严格的同步二阶段系统(设置 (setup)/构建 (build) 回调 (callback)),但 NaxRiscv 采用了一种更灵活的方法,使用 spinal.core.fber API 来分叉实例化线程,这些线程可以联锁,以确保可行的实例化顺序。

插件 API(Plugin API) 提供了一个类似 NaxRiscv 的系统来定义使用插件的可组合组件。

执行顺序

主要思想是您有多个 2 执行环节:

• 设置 (Setup) 环节,在此环节插件可以联锁/保留。其目的并非开始协调/实例化。

• 构建 (Build) 环节,在此环节插件可以协调/实例化硬件。

构建环节将不会在所有 FiberPlugin 完成其设置环节前启动。

class MyPlugin extends FiberPlugin {
val logic = during setup new Area {
// Here we are executing code in the setup phase
awaitBuild()
// Here we are executing code in the build phase
}
}
class MyPlugin2 extends FiberPlugin {
val logic = during build new Area {
// Here we are executing code in the build phase
}
}

简单示例

这是一个简单的虚设示例,其中包含一个将使用两个插件组合的 SubComponent:

import spinal.core._
import spinal.lib.misc.plugin._
// Let's define a Component with a PluginHost instance
class SubComponent extends Component {
val host = new PluginHost()
}
// Let's define a plugin which create a register
class StatePlugin extends FiberPlugin {
// during build new Area { body } will run the body of code in the Fiber build phase, in the context of the PluginHost
val logic = during build new Area {
val signal = Reg(UInt(32 bits))
}
}
// Let's define a plugin which will make the StatePlugin's register increment
class DriverPlugin extends FiberPlugin {
// We define how to get the instance of StatePlugin.logic from the PluginHost.It is a lazy val, because we can't evaluate it until the plugin is binded to its host.
lazy val sp = host[StatePlugin].logic.get
val logic = during build new Area {
// Generate the increment hardware
sp.signal := sp.signal + 1
}
}
class TopLevel extends Component {
val sub = new SubComponent()
// Here we create plugins and embed them in sub.host
new DriverPlugin().setHost(sub.host)
new StatePlugin().setHost(sub.host)
}

该TopLevel 会生成以下 Verilog 代码:

module TopLevel (
input wire clk,
input wire reset
);
SubComponent sub (
.clk (clk ), //i
.reset (reset) //i
);
endmodule
module SubComponent (
input wire clk,
input wire reset
);
reg [31:0] StatePlugin_logic_signal; //Created by StatePlugin
always @(posedge clk) begin
StatePlugin_logic_signal <= (StatePlugin_logic_signal + 32'h00000001); //incremented by DriverPlugin
end
endmodule

联锁/排序

插件可以通过 Retainer 实例相互联锁。每个插件实例都有一个内置锁,可以通过 retain/release 函数进行控制。这是一个基于上面的 简单示例的例子,但这次, DriverPlugin 将通过由其他插件(在我们的例子中是 SetupPlugin)设置的数量对 StatePlugin.logic.signal 递增。为了确保 DriverPlugin 不会过早生成硬件,SetupPlugin 使用 DriverPlugin.retain/release 函数。

import spinal.core._
import spinal.lib.misc.plugin._
import spinal.core.fiber._
class SubComponent extends Component {
val host = new PluginHost()
}
class StatePlugin extends FiberPlugin {
val logic = during build new Area {
val signal = Reg(UInt(32 bits))
}
}
class DriverPlugin extends FiberPlugin {
// incrementBy will be set by others plugin at elaboration time
var incrementBy = 0
// retainer allows other plugins to create locks, on which this plugin will wait before using incrementBy
val retainer = Retainer()
val logic = during build new Area {
val sp = host[StatePlugin].logic.get
retainer.await()
// Generate the incrementer hardware
sp.signal := sp.signal + incrementBy
}
}
// Let's define a plugin which will modify the DriverPlugin.incrementBy variable because letting it elaborate its hardware
class SetupPlugin extends FiberPlugin {
// during setup { body } will spawn the body of code in the Fiber setup phase (it is before the Fiber build phase)
val logic = during setup new Area {
// *** Setup phase code ***
val dp = host[DriverPlugin]
// Prevent the DriverPlugin from executing its build's body (until release() is called)
val lock = dp.retainer()
// Wait until the fiber phase reached build phase
awaitBuild()
// *** Build phase code ***
// Let's mutate DriverPlugin.incrementBy
dp.incrementBy += 1
// Allows the DriverPlugin to execute its build's body
lock.release()
}
}
class TopLevel extends Component {
val sub = new SubComponent()
sub.host.asHostOf(
new DriverPlugin(),
new StatePlugin(),
new SetupPlugin(),
new SetupPlugin() //Let's add a second SetupPlugin, because we can
)
}

这是生成的 verilog:

module TopLevel (
input wire clk,
input wire reset
);
SubComponent sub (
.clk (clk ), //i
.reset (reset) //i
);
endmodule
module SubComponent (
input wire clk,
input wire reset
);
reg [31:0] StatePlugin_logic_signal;
always @(posedge clk) begin
StatePlugin_logic_signal <= (StatePlugin_logic_signal + 32'h00000002); // + 2 as we have two SetupPlugin
end
endmodule

显然,这些示例对于它们的功能来说有些过度,总体上的思路更多地是:

• 协调/创建插件之间的接口(例如跳转 (jump)/刷新 (flush) 端口)

• 安排实例化(例如解码/调度规范)

• 提供一个可扩展的分布式框架(最小硬编码)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/386820.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c#实际开发长到的知识

基础科普: 个人建议先把rotion的库导入进来再操作,具体需要导入的库有,helper库包含了modbus通讯封装好的模块,而mvvm则可以用来做设计mvvm模块,你可以使用里面封装好的实现方法,用起来特别简单更容易实现其中的操作,但是我担心那天被卡脖子了啊啊啊,要是我罗工把库下…

【CTFHub】文件上传漏洞详解!

Webshell&#xff1a; 又称一句话木马。WebShell就是以网页文件形式存在的一种代码执行环境&#xff0c;主要用于网站管理、服务器管理、权限管理等操作。 WebShell根据不同的语言分为:ASP木马、PHP木马、JSP木马(上传解析类型取决于网站服务端编写语言类)&#xff0c;该类木马…

(二)延时任务篇——通过redis的key监听,实现延迟任务实战

前言 本节内容是关于使用redis的过期key&#xff0c;通过开启其监听失效策略&#xff0c;模拟订单延迟任务的执行流程。其核心原理是通过使用redis订阅与发布的方式&#xff0c;将过期失效的key通过广播的方式&#xff0c;发布给客户端&#xff0c;客户端可以监听此消息进而消…

LNMP动态网站环境部署

1、LINUX部署 stop firewallddisable selinux 2、Nginx部署 ​ vim /etc/yum.repos.d/nginx.repo [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck1 enabled1 gpgkeyhttps://nginx.org/keys/nginx_signing.…

【前端 · 面试 】JavaScript 之你不一定会的基础题(一)

最近我在做前端面试题总结系列&#xff0c;感兴趣的朋友可以添加关注&#xff0c;欢迎指正、交流。 争取每个知识点能够多总结一些&#xff0c;至少要做到在面试时&#xff0c;针对每个知识点都可以侃起来&#xff0c;不至于哑火。 JavaScript 之你不一定会的基础题 前言 面试往…

Windows蓝屏问题解决(电脑只要安装了VPN_SV独立客户端)必蓝屏

一、SERNEL_SECURITY_CHECK_FAILURE (139) 蓝屏分析 官方介绍蓝屏现象&#xff0c;官方Windows为了保护电脑&#xff0c;出现故障&#xff0c;自动蓝屏&#xff0c;避免损坏电脑的一种现象&#xff0c;别名buckcheck、蓝屏。 100%复现软件&#xff1a;天融信VPN&#xff0c;同事…

为了方便写CURD代码,我在UTools写了个插件SqlConvert来生成代码!

-1. 前言 为了方便摸鱼&#xff0c;我之前写过一个通过sql生成代码的工具&#xff0c;但是服务器到期了&#xff0c;也就懒得重新部署了。 技术框架是 SpringBoot MybatisPlus Velocity Vue ElementUI Sql-ParseeSql-Parser-ui 0. Utools应用安装 官网地址: https://u.too…

【HZHY-AI300G智能盒试用连载体验】使用YOLOv8进行车辆流量监测

目录 YOLOv8的RKNN模型 程序的部署 流量统计 本文首发于电子发烧友论坛&#xff1a;【新提醒】【HZHY-AI300G智能盒试用连载体验】 智能工业互联网网关 - 北京合众恒跃科技有限公司 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 环境准备好之后&#xff0c;接…

福建聚鼎:现在装饰画好做吗

在当今社会&#xff0c;随着人们审美情趣的提升和生活品质的改善&#xff0c;家居装饰画已经成为了一种流行的墙面装饰方式。许多人都在思考&#xff0c;现在做装饰画是否是一个好时机? “逆水行舟&#xff0c;不进则退。”在日新月异的市场中&#xff0c;装饰画行业的竞争愈发…

商用密码测评之对HTTPS(TLS)协议中各个参数解释

1、TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 是一个广泛使用的TLS&#xff08;传输层安全协议&#xff09;加密套件&#xff0c;它结合了多种技术和算法来确保网络通信的安全。下面是对该加密套件中各个参数的详细解释&#xff1a; 1. TLS 定义&#xff1a;TLS&#xff08;传…

JMeter 使用

1.JMeter 是什么&#xff1f; JMeter 是一款广泛使用的开源性能测试工具&#xff0c;由 Apache 软件基金会维护。它主要用于测试 Web 应用程序的负载能力和性能&#xff0c;但也支持其他类型的测试&#xff0c;如数据库、FTP、JMS、LDAP、SOAP web services 等。 2.特点&#x…

Infuse Pro for Mac全能视频播放器

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件…

Qt系统机制

Qt系统 Qt文件概述输入输出设备类QFileQFileInfoQt多线程Qt多线程常用API使用Qt多线程 线程安全互斥锁读写锁条件变量信号量 Qt网络QUdpSocketQNetworkDatagram设计一个UDP回显服务器QTcpServerQTcpSocketTcp版本的回显服务器HttpClient核心API Qt 音频Qt视频 Qt文件概述 ⽂件操…

【C++BFS】1020. 飞地的数量

本文涉及知识点 CBFS算法 LeetCode1020. 飞地的数量 给你一个大小为 m x n 的二进制矩阵 grid &#xff0c;其中 0 表示一个海洋单元格、1 表示一个陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相邻&#xff08;上、下、左、右&#xff09;的陆地单元格或跨过 gr…

【C++初阶】string类

【C初阶】string类 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 为什么学习string类&#xff1f; 1.1 C语言中的字符串 1.2 实际中 2. 标准库中的string类 2.1 string类 2.…

前缀表达式(波兰式)和后缀表达式(逆波兰式)的计算方式

缀是指操作符。 1. 前缀表达式&#xff08;波兰式&#xff09; &#xff08;1&#xff09;不需用括号&#xff1b; &#xff08;2&#xff09;不用考虑运算符的优先级&#xff1b; &#xff08;3&#xff09;操作符置于操作数的前面。&#xff08;如 3 2 &#xff09; 1.1 中…

《Programming from the Ground Up》阅读笔记:p75-p87

《Programming from the Ground Up》学习第4天&#xff0c;p75-p87总结&#xff0c;总计13页。 一、技术总结 1.persistent data p75, Data which is stored in files is called persistent data, because it persists in files that remain on disk even when the program …

hash表如何形成,hash函数如何计算,什么是hash冲突 如何解决 ,Golang map的底层原理及扩容机制

散列表 散列表&#xff08;hash表&#xff09;:根据给定的关键字来计算出关键字在表中的地址的数据结构。也就是说&#xff0c;散列表建立了关键字和 存储地址之间的一种直接映射关系。 问题&#xff1a;如何建立映射管血 散列函数:一个把查找表中的关键字映射成该关键字对应…

oracle语法介绍

Oracle数据库是关系型数据库管理系统之一&#xff0c;其SQL语法遵循标准的SQL规范&#xff0c;但也有一些自己的扩展。以下是一些Oracle SQL语法的基本示例&#xff1a; 1.选择数据&#xff1a; SELECT * FROM my_table; 1.插入数据&#xff1a; INSERT INTO my_table (colum…

RocketMQ事务消息机制原理

RocketMQ工作流程 在RocketMQ当中&#xff0c;当消息的生产者将消息生产完成之后&#xff0c;并不会直接将生产好的消息直接投递给消费者&#xff0c;而是先将消息投递个中间的服务&#xff0c;通过这个服务来协调RocketMQ中生产者与消费者之间的消费速度。 那么生产者是如何…