BUAA-CO-Preview
题目地址
CO 2023 讨论区优质帖汇总 | TripleCamera 的博客
基础知识
存储单位
- 最基础的存储单位是位(bit);在32位机中,1字节(Byte)= 8位(bit);1字(word)= 4字节(Byte), 1半字 = 2字节
- 2进制的一个数字占1位,16进制的一个数字表示16种情况,占4位,故一个字节只能存2位16进制数
P0
组合逻辑
2021_T1
4人(1个组长和3个组员)对议题进行投票表决。组长有一票否决权。如果组长一票否决,则议题被否决。如果组长正常投票(同意、反对或者弃权),则统计同意的人数和反对的人数。当同意人数大于反对人数,则议题通过,否则议题被否决。
请设计组合逻辑电路,实现这样子的一个投票表决器
同意 同意 弃权 一票否决 组长信号 00 01 10 组员信号 00 01与11 10
翻译:组长否决or(组员否决>=2)输出0,;组长同意and(组员同意>=2)输出1
可以先做一个统计输入数n个数的原件
- MAIN:
- 统计个数的原件:
2023_T1
给定五个8bit输入,输出一个8bit的在五个输入中没出现的最小正整数。例如输入为3,1,0,5,7;则输出为2。
用OR门将所有1塞进一个8bit数中,再用find_low_0找最小未出现1的位即可
2020_T2
信号名 方向 描述 tea[2:0] I 老师给的分数,二进制表示 s1[1:0] I 学生1给的分数 s2[1:0] I 学生2给的分数 total[3:0] O 总得分
当老师给的分数为0时,total为0;否则,total=tea+s1+s2
解析:先加,然后判断tea是否=0, 若=0则输出0,否则输出和。
加法时容易溢出,要先extend再加!!
FSM
相关知识
复位信号
- 同步复位:复位信号只有在时钟上升沿到来时,才能有效。也就是说,同步复位操作永远发生在时钟上升沿,即便复位信号提前到来,也无法立刻完成复位操作。
- 异步复位:无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。
- 若要搭建同步复位信号,应在状态转移时使用多路选择器,无reset信号时,将新状态存入寄存器,否则,将0存入寄存器;
异步信号只需要使用原件自带的clear引脚即可。
- Moore型output与input无关
- Mealy型的output与input有关
- 均可使用logisim的Combinational Analysis。
2020_T1
摆渡车有两条路线,可以在某一个站换乘,状态机需要输出下一个位置:
line0:
00 -> 11 -> 01 -> 10 -> 00
line1:
01 -> 10 -> 11 -> 01
解析:转移状态时按照转移要求填真值表即可,=但在与splitter连接时需要注意高低位!
本题不需要特殊的输出逻辑,所以没有输出模块,不代表其他题没有输出模块!!
- Main:
- 状态转移电路:
2023_T2
输入为2bit方向信号,1bit clk,1bit reset,异步复位。最开始位于1处,根据输入的2bit方向信息前往下一个位置,如果没有(或者撞墙)则停留在当前位置。输出为下一步的位置标号。输出4bit位置信号。Mealy型状态机
解析:初始状态不是0没关系,通过output模块,认为把初始状态设置成0即可。其余的就是打表。
有一点需要注意,hit应该需要第二个reg以保持与状态转移的同步性,否则会比状态转移快一周期!
Logisim_Helper
Arithmetic_library
- Bit Adder: 确定输入中有几个1。
东:输入; 西:输出。
- Bit Finder:
有多重模式:找最低位1、最高位1、最低位0、最高位0
东:输入; 西:输出; 南:是否找到目标数。
P1
组合逻辑
- 组合电路可以使用
assign
(配合三目运算符) =或always @(*)
实现= - 数据类型:
wire
:导线,不能存储数据。赋值使用assign
语句reg
:寄存器,有存储功能,一般在always
块中使用
不能用assign
赋值;可以“用来建模组合逻辑”??
mem[0][7:0]
:访问mem
中 0 号寄存器的7:0
位值
[bit+: width]
:从起始 bit 位开始递增,位宽为 width
[bit-: width]
:从起始 bit 位开始递减,位宽为 width
- 符号数与
$signed()
:reg
和wire
默认是无符号数,可以用$signed()
转换成有符号数。但若表达式同时存在有符号与无符号数,则转换符失效。$signed()
将括号内的表达式结果强制转换为有符号型。
- 常用语法:
assign
:assign a = b;
其中a
为wire
类型,并且要保证b
已被驱动
=不能在always
块和initial
块中使用=(也就是说,wire
型不能在always
等块中赋值)>>
与>>>
: 分别为逻辑右移与算数右移,逻辑右移将空出的最高位补0,算数右移补符号位。1
2
3
4a = 4'b1101;
assign ans = a >> 2; //逻辑右移ans = 4'b0011
assign ans = a >>> 3;//算数右移ans = 4'b0001
assign ans = $signed(a) >>> 3;//算数右移 ans =- 赋值:组合逻辑要用
=
阻塞赋值。 - 拼接:可以将几个信号的某些位拼接起来
1
2
3
4
5
6
7
8input [3:0] a;
input [3:0] b;
output [7:0] ans;
assign ans = {a[3:2],b};//将a的高2位与b拼接后,放在ans低位
//a = 4'b1010; b = 4'b1101; ans = 00101101;
ans = {2{a}};//将2个a拼接在一起后,放在ans低位
//a = 4'b1010; ans = 0...010101010; - 条件语句:
只能出现在顺序模块中(begin...end
)
只有当case
语句覆盖所有情况时才会生成组合逻辑,否则会生成时序逻辑(锁存器),因为需要保存当前状态。
因此一定不要忘记写default
1
2
3
4
5
6
7
8
9case(data)
0: out <= 4;
1: out <= 5;
2: out <= 2;
3: begin
out <= 1;
end
default: ;
endcase
2020_课下_T3
信号名 描述 imm[15:0] 输入16位数字 EOp 00:将imm进行符号扩展至32位 01:将imm进行高位零扩展至32位 10:将imm加载到高位,低位补0
这题好就好在它帮我想起了拼接
这种东西
1 | always @ (*) begin |
2020_T1
按照权重,计算得分:np(normal people),一票1分;vip,一票4分;vvip,一票16分。
信号名 方向 描述 np[31:0] I 31个普通人投票 vip[7:0] I 8个vip投票 vvip I 只有一个vvip res O 大于等于32分,res为1
1 |
|
数1的个数即可,需要注意:
for
循环,if
判断等都需要在always
块中使用always @ (*)
用的较少,此用法可以当组合逻辑使用- 计数器别忘了初始化,否则将恒为
xxx....
时序逻辑
always
语句块:
1 | always @ (posedge clk or negedge rst_n) //clk到达上升沿或rst_n到达下降沿触发 |
-
如果有多个
always
块,那么这些快是并行的 -
wire
型变量不能在其中被赋值,要想赋值必须定义为reg
; -
寄存器:
1 | //异步复位高电平有效: |
FSM
- 小函数:
1 | wire isd = (char >= "0" && char <= "9") ? 1 : 0; |
-
可以在
status 0
中进行初始化,这样当遇到default
时直接将status
置0,而无须进行其他操作 -
对于
status
的初始化: 可以在always
块内进行。 -
基本框架
组合逻辑实现转移,时序逻辑实现复位
可以采用Logisim中构造复位的思路
1 | //初始化 + 小函数 |
2020_T3
字符串状态机:
2020.2.2
2020-12.23
2020/3/30以上均是合法日期表示。
- 不能有前导零,08-17不合法
- 三种分隔符.-/,且必须保持一致
- 注意月份的天数,1~30,不考虑复杂情况
1 |
|
常见错误:
- 未定义变量就直接使用,ise不会报错,而是将该变量定义为1位宽wire型
要避免此类错误,可加上default_nettype none
,这样如果不事先定义,那么编译器就会报错。 - 在某些语句块中定义局部变量
- 组合逻辑电路与时序逻辑电路不能混用,组合逻辑不能写在
always
块内,否则会导致输出迟滞 for
循环内部的赋值不能用非阻塞赋值<=
1 | integer i; |
Isim调试技巧
在Instance and Process Name
中的uut目录下,选中非顶层模块(如always
模块),即可在右侧的Object
目录中看到中间变量,右键选择Add to Wave Window
,即可将对应信号添加到波形文件中。
BUAA-CO-Preview