Skip to main content

南大数电实验一,二,三,六,七配合NVBOARD

对于选择器的数据结构建模和行为建模,我一开始不是很理解,于是我问了一下某语料大模型chatgpt4,说行为建模和数据建模是verilog提供的不同层次的抽象,行为是更高的抽象层次,具体见图

要想理解行为建模,当然得利用一下综合工具啦,它推荐使用yosys开源工具,我经过一阵摸索,改造了一下npc文件夹,使得键入make sta即可综合+时序分析,不过令我意外的是综合竟然只是生成一个网格文件,不会生成真正电路图,但是其实是可以生成逻辑图的,于是我再写了个脚本,改了下makefile,让每次都会生成逻辑图,于是接下来就可以用NVBOARD实现实验一了

实验一

我还是使用的case语句,不过要注意case的匹配项默认是十进制的,我就在这卡了很久,在x2和x3始终输出不出来,因为11被解释成了十一,最主要的是我把代码丢给gpt他都没发现我的错误。

实验二

这个实验挺坑的,对于阳极晶体管,0才是亮,弄了我好久眼睛都看瞎了555

第二张图就是小脚本生成的逻辑图,我顺便又写了个脚本,可以把所有模块的全部综合成图片如图

这确实看的头都要晕了,你敢信这只是下面这么简单的case语句综合出来的电路图吗

实验三

这个实验让我把signed数的表示(补码)又复习了一遍,补码的本质实际上是循环,也就是模运算,正的在下面,负的在上面,然后再是正的,由于模运算,他会丢掉多出的那一个位,例如,一个正数加一个负数如果结果是正数的话,说明已经跳出当前的模了,类似于时钟到了下一个12小时。如图

在计算机中,大多只有加法器,对于减法,是先把减数变为其相反数再用加法运算,变为相反数就是所有位取反加一。例如-7(1001)->(0110)->7(0111),这时候要注意一个比较特殊的,最小的负数没有对应的正数相反数,这时候计算机应该也会按照这个去做吧(但是-8变为+8,本身这个数就产生了溢出)?不清楚(TODO

对于计算的溢出判断,两个正数相加可能溢出,两个负数相加也可能溢出,但是一正一负相加不会产生溢出,所以判断溢出也是先转化成加法,再看两个加数和结果的符号是否相同来判断,但是负数最小数(-8)按位取反加一,还是-8,按照之前的一个整数加一个负数永远不会溢出来看,这个不成立,所以应该把他看成特殊情况,所以用取反的结果和另一个数再和结果比较,也是就对应的讲义的第一种情况

assign t_no_Cin = {n{ Cin }}^B;
assign {Carry,Result} = A + t_no_Cin + Cin;
assign Overflow = (A[n-1] == t_no_Cin[n-1]) && (Result [n-1] != A[n-1]);这里

这挺巧妙的,因为只有最小的负数按位取反加一会把符号位给覆盖掉,也就是本身这个数就有溢出

我只是把我刚想的一股脑全写上去了,很有可能逻辑不通,我也只是把它当作笔记或者记录(众所周知笔记只有自己看得懂)

这是我写的报warning:latch的代码,说是所有变量都必须初始化(假如没在每个case初始化)

改正后结果如下,最后发现这个也会报错(在用yosys的时候),应该把局部变量声明在always块外

0101+0101,溢出位OF(LD6)亮,功能p=000加法,结果r=1010

p=001减法,0001-1001,1-(-7),溢出位LD6亮

p=110,比较大小,1000(-8)<0001(1)true,结果LD0为1,请忽视flag灯

这个挺好看的吧,请看下图

alu4的内部

实验六

这个写的比较顺嘿嘿

实验七

一开始看这个实验要求是的时候感觉手足无措,感觉和前面的难度不匹配,好在NVBOARD对于接收键盘输入并不难,好像ps2_clk也不需要仿真时自己设计,可是感觉他给我的三个要求还是挺难的。

1.从没写过ROM 2.没思路 3.我想用FSM实现(我也从没写过FSM),但是感觉好麻烦。

遇到对于自己比较困难的问题,应该想方设法的先做出来一个雏形,可以不具备上述的三个要求,就像托尼在山洞里造的第一版钢铁侠,也是简陋无比,但谁曾想最后能变成纳米级的盔甲。所以,冻手吧。

第一步,显示键码

第二步,实现一个FSM,state1:按下(1);state0:没按下(0)。state1时,显示键码;state0时,低位全灭。state1->state0时,计数器加一。

这一步实现得真难,最主要的是时序时序时序时序时序!!!!,verilog代码真的和其他编程语言不同,毕竟人家是产生硬件的语言,你每想一步,你都要清楚的明白,这一步是在哪个clock发生的,并且要想这一步的clock同步发生的事情有什么,并且还要确保你的组合逻辑的时间必须要短于一个clk(实际上还要更短),比方说,ps2_keyboard模块打一拍只传输了一个二进制代码,但是与此同时,你的状态机也在同步打拍子,也就是说传输11个字节(实际上是10个)同步打了10拍,而状态机在这十拍内不能出岔子,这真的调了我好久,最后好在想通了,真的是,以后写时序逻辑必须要心中完全清楚再vim xxx.v。好了,为了庆祝,就拍了个视频,请看VCR:

第三步,实现一个ROM,ROM的输入为键码值,输出为acsii码值。

写到这里发现写不了一点,ROM完全不会写,于是打算先去写实验五,我去看了一下实验五,不过还是没写,去学了一下rom的写法

计数器count=5 ;acsii=0x65 ;‘e’的扫描码=24。以下是逻辑图,ps2模块产生扫描码,扫描码是fsm的输入,fsm输出计数器,扫描码,扫描码再给rom转换。

完结撒花。