chisel快速入门(三)

前一篇见此:

chisel快速入门(二)_沧海一升的博客-CSDN博客简单介绍了chisel,使硬件开发者能快速上手chisel。https://blog.csdn.net/qq_21842097/article/details/121418806

十四、模块的功能创建

        制造用于模块构造的功能接口也是有用的。例如,我们可以构建一个构造函数,它将多路复用器输入作为参数,并返回多路复用器输出:

object Mux2 {def apply (sel: UInt, in0: UInt, in1: UInt) = {val m = new Mux2() m.io.in0 := in0 m.io.in1 := in1 m.io.sel := sel m.io.out}
}

        其中对象Mux2在Mux2模块类中创建一个Scala单例对象,并且apply定义了创建Mux2实例的方法。有了这个Mux2创建功能,Mux4的规格现在明显更简单。

class Mux4 extends Module { val io = new Bundle {val in0 = UInt(INPUT, 1)val in1 = UInt(INPUT, 1) val in2 = UInt(INPUT, 1) val in3 = UInt(INPUT, 1) val sel = UInt(INPUT, 2) val out = UInt(OUTPUT, 1)}io.out := Mux2(io.sel(1), Mux2(io.sel(0), io.in0, io.in1), Mux2(io.sel(0), io.in2, io.in3))
}

        选择输入非常有用,以至于 Chisel 将其内置并称之为 Mux。 然而,与上面定义的 Mux2 不同,内置版本允许 in0 和 in1 上的任何数据类型,只要它们有一个共同的超类。

        Chisel提供MuxCase,其本质上是一个n-way Mux。

MuxCase(default, Array(c1 -> a, c2 -> b, ...))

十五、多态性和参数化

        Scala是一种强类型语言,使用参数化类型来指定通用函数和类。 在本节中,我们展示了Chisel用户如何使用参数化类来定义自己的可重用函数和类。

1、参数化函数

        前面我们在Bool上定义了Mux2,但现在我们展示如何定义一个通用的多路复用器功能。我们使用一个布尔条件和con和alt参数(对应于then和else表达式)来定义一个T类型的函数:

def Mux[T <: Bits](c: Bool, con: T, alt: T): T { ... }

        其中T需要是Bits的子类。Scala确保在Mux的每个使用中,它可以找到实际的con和alt参数类型的公共超类,否则会导致Scala编译类型错误。

2、参数化类

        与参数化函数一样,我们也可以参数化类,使它们可重用程度更高。例如,我们可以将Filter类概括为可以使用任何类型的链接。

        我们可以通过参数化FilterIO类和定义构造函数采取零参数类型构造函数来做到这点,如下所示:

class FilterIO[T <: Data](type: T) extends Bundle { val x = type.asInput.flipval y = type.asOutput
}

        我们现在可以通过定义一个模块类来定义Filter,该模块类也接收一个链接类型构造函数参数,并将其传递给FilterIO接口构造器:

class Filter[T <: Data](type: T) extends Module { val io = new FilterIO(type)...
}

        另一个例子,通用FIFO可以这样定义,并使用如下:

class DataBundle extends Bundle { val A = UInt(width = 32)val B = UInt(width = 32)
}
object FifoDemo {def apply () = new Fifo(new DataBundle, 32)
}class Fifo[T <: Data] (type: T, n: Int) extends Module {val io = new Bundle {val enq_val = Bool(INPUT) val enq_rdy = Bool(OUTPUT) val deq_val = Bool(OUTPUT) val deq_rdy = Bool(INPUT) val enq_dat = type.asInput val deq_dat = type.asOutput}val enq_ptr = Reg(init = UInt(0, sizeof(n)))val deq_ptr = Reg(init = UInt(0, sizeof(n)))val is_full = Reg(init = Bool(false))val do_enq  = io.enq_rdy && io.enq_valval do_deq  = io.enq_rdy && io.deq_val val is_empty = !is_full && (enq_ptr === deq_ptr)val deq_ptr_inc = deq_ptr + UInt(1)val enq_ptr_inc = enq_ptr + UInt(1)val is_full_next = Mux(do_enq && ~do_deq && (enq_ptr_inc === deq_ptr), Bool(true), Mux(do_deq && is_full, Bool(false), is_full)) enq_ptr := Mux(do_enq, enq_ptr_inc, enq_ptr) deq_ptr := Mux(do_deq, deq_ptr_inc, deq_ptr) is_full := is_full_nextval ram = Mem(n) when (do_enq) {ram(enq_ptr) := io.enq_dat }io.enq_rdy := !is_full io.deq_val := !is_empty ram(deq_ptr) <> io.deq_dat
}

        对FIFO定义通用解耦接口,可以简化IO:

class DecoupledIO[T <: Data](data: T) extends Bundle {val ready = Bool(INPUT)val valid = Bool(OUTPUT)val bits = data.clone.asOutput 
}class DecoupledDemo
extends DecoupledIO()( new DataBundle )class Fifo[T <: Data] (data: T, n: Int) extends Module {val io = new Bundle {val enq = new DecoupledIO( data ).flip() val deq = new DecoupledIO( data )}... 
}

十六、多时钟域

1、创建时钟域

        为了使用多个时钟域,用户必须创建多个时钟。 在Chisel中,时钟是使用复位信号参数创建的第一级节点,定义如下:

class Clock (reset: Bool) extends Node { def reset: Bool // returns reset pin
}

        在Chisel中有一个内置的隐式时钟,状态元素默认使用:

var implicitClock = new Clock( implicitReset )

        状态元素和模块的时钟可以使用名为clock的附加命名参数来定义:

Reg(... clock: Clock = implicitClock) 
Mem(... clock: Clock = implicitClock) 
Module(... clock: Clock = implicitClock)

2、跨时钟域

        有两种方式可以定义电路在时钟域之间发送数据。第一种也是最原始的方式就是使用由两个寄存器组成的同步器电路,如下所示: 

// signalA is in clock domain clockA,
// want a version in clockB as signalB
val s1 = Reg(init = UInt(0), clock = clockB) 
val s2 = Reg(init = UInt(0), clock = clockB)
s1 := signalA
s2 := s1;
signalB := s2

        由于亚稳性问题,该技术只限于在域之间传递一位数据。

        在域之间发送数据的第二种和更一般的方式是通过使用异步fifo:

class AsyncFifo[T<:Data](gen: T, entries: Int, enq_clk: Clock, deq_clock:Clock) extends Module

        当通过指定标准fifo参数和两个时钟,然后使用标准解耦ready/valid信号从时钟域clockA到clockB获取一个版本的signalA时:

val fifo =
new AsyncFifo(Uint(width = 32), 2, clockA, clockB)
fifo.io.enq.bits := signalA
signalB := fifo.io.deq.bits
fifo.io.enq.valid := condA
fifo.io.deq.ready := condB

3、后端多时钟处理

        每个 Chisel 后端都需要用户以后端特定的方式设置和控制多个时钟。 为了展示如何驱动多时钟设计,我们以具有两个模块的硬件为例进行说明,该例子使用 AsyncFifo 与不同时钟的每个模块进行通信:fastClock 和 slowClock。

        在Verilog中:

  • Chisel为每个时钟/复位创建一个新端口,
  • Chisel将所有的时钟连到顶层模块
  • 用户必须要为每个时钟i创建一个always块时钟驱动
module emulator;reg fastClock = 0, slowClock = 0, resetFast = 1, resetSlow = 1; wire [31:0] add, mul, test;always #2 fastClock = ~fastClock;always #4 slowClock = ~slowClock; initial begin# 8resetFast = 0; resetSlow = 0; #400$finish;
end
ClkDomainTest dut (.fastClock(fastClock), .slowClock(slowClock), .io_resetFast(resetFast),.io_resetSlow(resetSlow),.io_add(add), .io_mul(mul), .io_test(test));
endmodule

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

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

相关文章

Redis作者摊上事了:多人要求修改Redis主从复制术语master/slave

作者 | ANTIREZ、小智近日&#xff0c;Redis 作者在 GitHub 上发起了一个“用其他词汇代替 Redis 的主从复制术语”的 issue。有人认为 Redis 中的术语 master/slave &#xff08;主人 / 奴隶&#xff09;冒犯到了别人&#xff0c;要求 Redis 作者 ANTIREZ 修改这个术语&#x…

C字符串数组赋值

C字符数组赋值 举例如下&#xff1a; char a[10]; 1、定义的时候直接用字符串赋值 char a[10]"hello"; 注意&#xff1a;不能先定义再给它赋值&#xff0c;如 char a[10]; a[10]"hello"; 这样是错误的&#xff01; 2、对数组中字符逐个赋值 char a[10]{h…

WP8.1使用HttpClient类

Uri uri new Uri("http://www.cnsos.net/weburl/index.htm", UriKind.Absolute); HttpClient myClient new HttpClient(); string result await myClient.GetStringAsync(uri); await new MessageDialog(result).ShowAsync(); 转载于:https://www.cnblogs.com/wzw…

HttpClinet学习笔记

本文为学习httpClient学习过程中转载的文章&#xff0c;若涉及版权请留言。 ----------------------------- 前言 超文本传输协议&#xff08;HTTP&#xff09;也许是当今互联网上使用的最重要的协议了。Web服务&#xff0c;有网络功能的设备和网络计算的发展&#xff0c;都持续…

CMOS图像传感器——2021产品选谈

据Yole统计,2020年全球CMOS图像传感器(CIS)市场规模为207亿美元,出货量为70.08亿颗。跟其它半导体器件一样,CIS也因为疫情和生产周期长,以及各种市场因素,而导致采购和供应链紧张。Yole预计2021年将趋于平稳,销售额相比2020年略有增长(3.2%),将达到214亿美元,出货量…

LINUX 下tcp 和 udp 套接字收发缓冲区的大小决定规则 .

const int udp_recvbufsize 384 * 1024 ; int result ::setsockopt(m_hSocket, SOL_SOCKET, SO_RCVBUF, (char*)&udp_recvbufsize, sizeof(int)); // 如果是由于你发送的速率较高而引起的,如500kbit/s, 那么设置大点的UDP缓冲区是比较有效的. LINUX 下tcp 和 udp 套接…

C++匿名对象

匿名对象&#xff1a; string("hello")就是匿名对象&#xff1b; 匿名对象当做参数引用时必须加const; 转载于:https://www.cnblogs.com/achao123456/p/9634810.html

MVC源码分析 - Action查找和过滤器的执行时机

接着上一篇, 在创建好Controller之后, 有一个 this.ExecuteCore()方法, 这部分是执行的. 那么里面具体做了些什么呢? //ControllerBaseprotected virtual void Execute(RequestContext requestContext) {if (requestContext null){throw new ArgumentNullException("req…

CCIE-MPLS基础篇-实验手册

又一部前期JUSTECH&#xff08;南京捷式泰&#xff09;工程师职业发展系列丛书完整拷贝。 MPLS&#xff08;Multi-Protocol Label Switching&#xff09; 目录 1&#xff1a;MPLS 基础实验.... 3 1.1实验拓扑... 3 1.2实验需求&#xff1a;... 3 1.3实验步骤... 3 1.4校验…

数学形态学滤波学习

一、概述 数学形态学是建立在集合论基础上了一门学科。具体在图像处理领域,它把形态学和数学中的集合论结合起来,描述二值或灰度图像中的形态特征,来达到图形处理的目的。形态学主要是通过结构元素和图像的相互作用对图像进行拓补变换从而获得图像结构信息,通过对结构信息的…

RCA/BNC接口

RCA接口&#xff08;消费类市场&#xff09; RCA 是Radio Corporation of American的缩写词&#xff0c;因为RCA接头由这家公司发明的。RCA俗称莲花插座&#xff0c;又叫AV端子&#xff0c;也称AV 接口&#xff0c;几乎所有的电视机、影碟机类产品都有这个接口。它并不是专门为…

Retrofit2源码解析——网络调用流程(下)

Retrofit2源码解析系列 Retrofit2源码解析(一)Retrofit2源码解析——网络调用流程(上)本文基于Retrofit2的2.4.0版本 implementation com.squareup.retrofit2:retrofit:2.4.0 复制代码上次我们分析到网络请求是通过OkHttpCall类来完成的&#xff0c;下面我们就来分析下OkHttpCa…

spring EL 实现ref的效果

之前学习basic的时候有个疑问就是不知道如何实现bean中引用其他的bean的属性&#xff0c;当时是用ref来实现对其他bean的引用&#xff0c;但是ref必需引用的是一个常量。所以这种方式来实现对其他bean中的属性的引用是不合理的。 当我看到Spring Expression Language时发现原来…

2021手机CIS技术趋势总结

手机摄像头CIS&#xff08;CMOS图像传感器&#xff09;自从突破1亿像素以后&#xff0c;再谈像素数量增大&#xff0c;似乎已经很难让市场产生激烈反应了。这两年电子工程专辑对于手机摄像头CIS&#xff0c;以及更多领域不同类型的图像/视觉传感器&#xff08;如ToF、基于事件的…

关于Unity中NGUI的背包实现之Scrollview(基于Camera)

基于UIPanel的scrollview实现方式在移动设备上的性能不如基于camera的方式。因为UIPanel的scrollview实现方式要渲染很多的道具图&#xff0c;性能自然就降低了。如果是用第二个摄像机camera的方式&#xff0c;物体并没有动&#xff0c;只是拖动第二个摄像机摄像机&#xff0c;…

YUV422/420 format

(在本文中&#xff0c;U 一词相当于 Cb&#xff0c;V 一词相当于 Cr。) YUV422 format as shown below 4:2:2 表示 2:1 的水平取样&#xff0c;没有垂直下采样 YUV420 format as shown below4:2:0 表示 2:1 的水平取样&#xff0c;2:1 的垂直下采样. YUV4:2:0并不是说只有U&…

vue部署问题

history模式配置后刷新404的解决办法! 第一种 nginx配置 在usr/local/nginx/conf/vhost 下 域名.conf配置文件修改或添加 第一种方案server {##在server下添加或在location里面添加以下代码location / {if (!-e $request_filename) {rewrite ^(.*)$ /index.html?s$1 last…

位域

有些信息在存储时&#xff0c;并不需要占用一个完整的字节&#xff0c; 而只需占几个或一个二进制位。例如在存放一个开关量时&#xff0c;只有0和1 两种状态&#xff0c; 用一位二进位即可。为了节省存储空间&#xff0c;并使处理简便&#xff0c;C语言又提供了一种数据结构&a…

数字后端——ECO

目录 一、概述 二、ECO分类 1、按时间节点 1&#xff09;流片前的ECO 2&#xff09;流片过程的ECO 3&#xff09;流片后的ECO 2、按网表是否改变 1&#xff09;功能ECO 2&#xff09;时序ECO 三、ECO处理内容 1、设计规则违例 1&#xff09;提升标准单元驱动力 2…

Uncaught TypeError: Cannot read property 'length' of null错误怎么处理?

Uncaught TypeError: Cannot read property length of null 错误怎么处理&#xff1f; 1.可能是返回的datagrid数据格式有问题&#xff0c;比如{"total":0,"rows":null}&#xff0c;改为{"total":0,"rows":"[]"}就可以了 if…