参考: 《CPLD与单片机综合应用技术》(周立功)
实验板: 网助二号
例 5.2.3
module adder(count, sum, a, b, cin);
input [2:0] a, b;
input cin;
output count;
output [2:0] sum;
assign {count, sum} = a + b + cin;
endmodule
★ 此例描述了一个名为adder的三位加法器,可根据2个三比特数a、b及进位(cin)计算出和(sum)以及向上进位(count)。 "{ }"是拼接符,把count和sum拼接为一个4位的信号。
如何验证其正确性呢?开始将a的3个端口接了三个拨码开关,b的3个端口接了三个按钮开关(因为板上资源只有4个拨码开关和4个按钮开关),将相加得到的和sum的三个端口接三个LED显示结果, 进位位count同样接LED显示是否有进位,进位cin置为0。虽然这样的接法可以通过开关输入两个加数,也能看到结果,得出该模块的正确性,但总觉得这么手工输入的办法有些蠢,也没有发挥这块板MCU+CPLD综合的优势,于是产生如下方案。
用51单片机的P0口低3位产生被加数a, P2口低3位产生加数b, 得到的和还有进位仍然通过LED显示。开始想用二重循环产生所有的组合,被加数有8种情况,加数有8种情况,共可得到8×8=64种组合,但这样一来即不容易验证,二来也没必要,所以最终决定将b数值确定为01h, 而a的值由000b递增为111b这8个状态,分别与b相加后得到结果为001b,010b,011b,……,111b(第7个结果),再加01h后将产生进位,与后三位合并后为1000b,每个状态后延时1s以便观察,如此循环。上述过程中前一级的进位cin接地,即始终为0。
51单片机程序:
org 0000h
start: mov p2, #01h
mov a, #00h
lop: mov p0, a
inc a
call delay_1s
ajmp lop
delay_1s: mov r0,#2
temp1: mov r1,#0ffh
temp2: mov r2,#10
temp3: mov r3,#100
djnz r3,$
djnz r2,temp3
djnz r1,temp2
djnz r0,temp1
ret
end
编译下载到到实验板上实测,得到预计结果,只是输出看着有些别扭,因为板上的LED显示亮表示0,灭表示1。
为了帖个结果图上来,还是用Porteus模拟了一下。由于Portues库中没有这种三位加法器(或许有我不知道), 所以模拟的时候用的是四位全加器7483, 为了用它模拟三位的, 将两个加数的第四位都置0(接地), 前一级的进位C0置0(接地),而向下一级的进位应该是7483的"和"输出端的第4位,而非其本身的进位C4。模拟结果如下(输出结果按BCD码):
可知其结果是正确的:P2口送加数为定值01h,P0口送被加数由000b递增到111b, 产生8个结果如下:
╔──────────────╗
│ a b cin sum count│
├──────────────┤
│ 000b 01h 0 001b 0 │
│ 001b 01h 0 010b 0 │
│ 010b 01h 0 011b 0 │
│ 011b 01h 0 100b 0 │
│ 100b 01h 0 101b 0 │
│ 101b 01h 0 110b 0 │
│ 110b 01h 0 111b 0 │
│ 111b 01h 0 000b 1 │
╚──────────────╝
又随意设置了几个b的值, 再次验证显然还是正确的, 将前一级的进位cin设置为1再重复做上述实验仍然得到正确结果。
评论