2021.7.2
1把language里面的vectors最后两题撸完。
(18)在concatenation中可以用系数来表示成倍的小向量。以及对有符号数进行扩容的方法就是把它的最高项(符号值)扩充,负数的符号值是1,正数是0.
(19)把五个wire变量按不同方式合成两个大向量,然后拿他们按位求同或。
//我在解这题的时候忘了一件事情,就是在声明了向量大小的情况下,直接引用这个向量的名字实际上是按顺序引用这个向量的所有元素!解这题的时候我甚至还想用循环语句!
2.module部分的话起个头吧。
(20)介绍了模块(module),告诉我们模块可以拿来做分层式设计。
在连接模块内和模块外的信号的时候,可以使用引用端口名称或引用端口位置两种方式。
①引用端口位置
和C语言类似,在实例化模块的时候,端口根据从左到右的顺序来连接。例如:
mod_a instance1 ( wa, wb, wc );
//mod_a类型的模块被实例化,然后我们给它一个名字”instance1”。然后把wa、wb、wc按顺序依次连接到三个端口”in1”、”in2”、”out”。
这样的方式有一个缺点,如果模块的端口表发生变化,所有实例化都得改变来匹配新模块。(这里我不大理解,新模块指的是mod_a吗?说到底我还是没理解实例化的含义)
②引用端口名称
即使端口表发生变化,这种连接方式也不需要更改,但是它写法比较麻烦。例如:
mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) ); //.port_position(signal)
//记得位置前面有个点
//这种写法比较严谨,我个人推荐
//养成良好的编程习惯,善用换行和缩进,比如:
mod_a instance1 ( .in1(a), .in2(b), .out(out) );
可以写成:
mod_a instance1 (
.in1(a),
.in2(b),
.out(out)
);
(21)给定module,让我用引用端口位置的方式实例化一个instance出来。
(22)用引用端口名称的方式实例化一个instance,简单。
(23)帮我定义好模块my_dff了,就是个D触发器(边沿触发),有两个输入clk、d,一个输出q。让我在top_module里面插入三个D flip-flop。我的思路是在前面声明两个中间值q1,q2,参考答案也是这么想的。
(24)把连接模块端口的单个信号换成向量。注意:wire向量长度和端口长度不一定要一样,但是如果两者不一致的话编译器会自动用0逻辑来填充或者溢出等操作来使两者长度一致。
这个练习给定模块是8位输入输出的D触发器:
module my_dff8 (
input clk,
input [7:0] d,
output [7:0] q
);
然后级联三个这样的触发器,把三个8位输出q和两位选择信号sel接入MUX中,最后有一个8位输出,由两位sel信号选择top_module的输出是哪一个环节的q值。(实际意义:选择信号决定delay输入的信号d到输出多久)
我的思路是:声明三个wire向量q1, q2, q3用作中间值,把这三个加上d输入到MUX。然后再声明一个名为MUX的module用于数据选择,再在top_module中实例化MUX,把待选择的四个向量和选择信号放进去,最终输出q值。
//在写这个代码的时候我遇到了报错:
wire [7:0]q1, [7:0]q2, [7:0]q3; //ERROR:如果是声明向量,不要连续声明
//这道题我竟然写了61行代码,不过出于让代码看起来更优雅所以我用了很多换行符
//参考答案用了always过程块,然后在里面用了case语句,emm也行吧,和我这个比起来我觉得它那个不够优雅
//查看了我之前的笔记,条件语句都是串行执行,然后case语句会被综合成查找表,虽然延迟低但是电路规模大