1组合逻辑电路--基本门电路1.1基本门电路1.1.1结构化描述⽅式代码如下
View Code1 module logics2 (3 input iA,4 input iB,5 output oAnd,6 output oOr,7 output oNot8 );9
10 and and_inst(oAnd,iA,iB);11 or or_inst(oOr,iA,iB);12 not not_inst(oNot,iA);13
14 endmodule
最底层的是门级原语and or not RTL级视图
testbench如下
View Code
1 `timescale 1 ns/ 1 ns2 module logics_tb();
34 reg ia;5 reg ib;6
7 wire oAnd;8 wire oOr;9 wire oNot;1011 initial12 begin13 ia=0;14 #40 ia=1;15 #40 ia=0;16 #40 ia=1;17 #40 ia=0;18 end1920 initial21 begin22 ib=0;23 #40 ib=0;24 #40 ib=1;25 #40 ib=1;26 #40 ib=0;27 end28
29 logics logics_inst30 (31 .iA(ia),32 .iB(ib),33 .oAnd(oAnd),34 .oOr(oOr),35 .oNot(oNot)36 );37
38 endmoduleRTL级仿真图形如下
GATE级仿真图如下
可见RTL级仿真是理想的,GATE级仿真考虑了延迟和信号开始的不确定。1.1.2采⽤流描述⽅法代码如下
View Code1 module logics2 (3 input iA,4 input iB,5 output oAnd,6 output oOr,7 output oNot8 );9
10 assign oAnd=iA&iB11 assign oOr=iA|iB;12 assign oNot=~iA;13
14 endmodule
RTL级视图,仿真图形同上。1.1.3 采⽤⾏为描述⽅式代码如下
View Code
1 module logics2 (3 input iA,4 input iB,5 output reg oAnd,6 output reg oOr,7 output reg oNot8 );9
10 always @(*)11 begin12 oAnd=iA&iB13 oOr=iA|iB;14 oNot=~iA;15 end16
17 endmodule
always@()括号内的敏感信号填*,则综合器⾃动加上敏感信号。
由于always语句中左边信号都要是寄存器型,故输出信号定义为寄存器型。描述组合逻辑时,always中使⽤阻塞赋值⽅式。RTL级视图及仿真图形同上。
2组合逻辑电路--多路选择器与多路分解器1.2多路选择器
1.2.1不带优先级的多路选择器四路选择器如下代码如下
View Code
1 module multiplexer2 (3 input iA,4 input iB,5 input iC,6 input iD,7 input [1:0] iSel,8 output reg oQ
9 );10
11 always @(*)12 begin13case(iSel)142'b00 : oQ=iA;152'b01 : oQ=iB;162'b10 : oQ=iC;172'b11 : oQ=iD;18 endcase19 end20
21 endmodule
case语句如果没有全部包含所有的情况,则⼀般要⽤default语句将信号默认赋值为0,否则会出现锁存器,使得仿真结果不⼀致。
RTL级视图如下:
testbench如下
View Code
1 `timescale 1 ns/ 1 ns2 module logics_tb();34 reg ia;5 reg ib;6
7 wire oAnd;8 wire oOr;9 wire oNot;10
11 initial12 begin13 ia=0;14 #40 ia=1;15 #40 ia=0;16 #40 ia=1;17 #40 ia=0;18 end1920 initial21 begin22 ib=0;23 #40 ib=0;24 #40 ib=1;25 #40 ib=1;26 #40 ib=0;27 end28
29 logics logics_inst30 (31 .iA(ia),32 .iB(ib),33 .oAnd(oAnd),34 .oOr(oOr),35 .oNot(oNot)36 );37
38 endmodule
initial语句和always语句左边的信号类型都要为reg。RTL级仿真图形如下
1.2.2 带优先级的多路选择器代码如下
View Code
1 module multiplexer2 (3 input iA,4 input iB,5 input iC,6 input iD,7 input [1:0] iSel,8 output reg oQ9 );10
11 always @(*)12if(iSel==2'b00)13 oQ=iA;
14else if(iSel==2'b01)15 oQ=iB;
16else if(iSel==2'b10)17 oQ=iC;18else19 oQ=iD;20
21 endmoduleRTL级视图如下
1.2.3多路分解器
⼀路输⼊,三路输出分解器代码如下
View Code
1 module de_multiplexer2 (3 input iA,4 input [1:0] iSel,5 output reg oA,6 output reg oB,7 output reg oC8 );9
10 always @(*)11 begin
12 oA=0;oB=0;oC=0;13case(iSel)142'b00 : oA=iA;152'b01 : oB=iA;162'b10 : oC=iA;17default :;18 endcase19 end20
21 endmoduleRTL级视图如下
testbench代码如下
View Code
1 `timescale 1ns/1ns2 module de_multiplexer_tb;3 reg ia;4 reg [1:0] isel;5 wire oa;6 wire ob;7 wire oc;89 initial10 begin11 ia=0;12 forever13 #10 ia=~ia;14 end1516 initial17 begin18 isel=2'b00;19 #20 isel=2'b01;20 #20 isel=2'b10;21 #20 isel=2'b11;22 #20 $stop;23 end24
25 de_multiplexer de_multiplexer_inst26 (27 .iA(ia),28 .iSel(isel),29 .oA(oa),30 .oB(ob),31 .oC(oc)32 );33
34 endmoduleRTL级仿真波形如下
1组合逻辑电路--编码器和译码器1.3.1 编码器
4输⼊2输出编码器代码如下
View Code1 module encoder2 (
3 input [3:0] iA,4 output reg [1:0] oQ5 );6
7 always @(*)8 begin9 oQ=2'b00;10case(iA)
114'b0001:oQ=2'b00; 124'b0010:oQ=2'b01; 134'b0100:oQ=2'b10; 144'b1000:oQ=2'b11; 15default :;16 endcase17 end18
19 endmoduleRTL级视图如下
testbench代码如下
View Code
1 `timescale 1ns/1ns2 module encoder_tb;3
4 reg [3:0] ia;5 wire [1:0] oq;67 initial8 begin9 ia=4'b0000;10 #20 ia=4'b0001;11 #20 ia=4'b0010;12 #20 ia=4'b0100;13 #20 ia=4'b1000;14 #20 $stop;15 end16
17 encoder encoder_inst18 (19 .iA(ia),20 .oQ(oq)21 );22
23 endmoduleRTL级仿真波形如下
1.3.2 优先编码器
真值表如下,参考艾⽶电⼦
代码如下
View Code1 module encoder2 (
3 input [3:0] iA,4 output reg [1:0] oQ5 );6
7 always @(*)8 begin9 oQ=2'b00;10if(iA[3])oQ=2'b11;
11else if(iA[2])oQ=2'b10; 12else if(iA[1])oQ=2'b01; 13else oQ=2'b00; 14 end15
16 endmoduleRTL级视图
RTL级仿真波形
1组合逻辑电路--算术运算电路1.4.1 +、-、*、/、%电路
(1)加法电路:每1位⼤约消耗1个LE,⽰例代码如下
View Code1 module arithmetic2 (
3 input [7:0] iA,4 input [7:0] iB,5 output [8:0] oAdd6 );
7
8 assign oAdd=iA+iB;9
10 endmoduleRTL级视图如下
testbench如下
View Code
1 `timescale 1ns/1ns2 module arithmetic_tb;3
4 reg [7:0] ia=8'b1011_0111;5 reg [7:0] ib=8'b0100_1000;6 wire [8:0] oadd;7
8 initial #100 $stop;9
10 arithmetic arithmetic_inst11 (12 .iA(ia),13 .iB(ib),14 .oAdd(oadd)15 );16
17 endmodule仿真波形如下
(2)乘法电路
代码将加法电路代码中语句oAdd=iA+iB;改为oMul=iA*iB;即可。oMul位宽为[15:0] 代码综合后乘法单元直接调⽤的CycloneII嵌⼊式乘法器lpm_mult
RTL级视图
仿真波形图
(3)除法电路
代码将加法电路代码中语句oAdd=iA+iB;改为oDiv=iA/iB;即可。oDiv位宽为[7:0]代码综合后除法单元直接调⽤的lpm_divide实现的
取余运算也很消耗资源,每位运算⼤约消耗10LE.RTL级视图如下
RTL级波形仿真
(4)取余运算
代码将加法电路代码中语句oAdd=iA+iB;改为oMod=iA%iB;即可。oMod位宽为[7:0] 代码综合后取余运算直接调⽤的lpm_divide实现的
除法运算很消耗资源,每位运算⼤约消耗10LE.RTL级视图如下
RTL级波形仿真
1.4.2 数据⽐较器
代码如下,风格⾮常类似C语⾔
View Code1 module arithmetic2 (
3 input [3:0] iA,4 input [3:0] iB,5 output oEQ,6 output oGT,7 output oLT,8 output oGT_EQ,9 output oLT_EQ,10 output oNEQ11 );12
13 assign oEQ=(iA==iB),14 oNEQ=(iA!=iB),15 oGT=(iA>iB),16 oLT=(iA
17 oGT_EQ=(iA>=iB),18 oLT_EQ=(iA<=iB);19 endmoduleRTL级视图如下
RTL级仿真波形如下
1.4.3 移位电路1.4.3.1 逻辑移位电路代码如下
View Code1 module arithmetic2 (
3 input [7:0] iA,4 input [3:0] iBit,5 output [7:0] osll,6 output [7:0] osrl7 );8
9 assign osll=iA<10 osrl=iA>>iBit;11 endmoduleRTL级视图如下
RTL级仿真波形
1.4.3.2 算术移位
算术移位运算符为<<<,>>>;
有符号数算术移位和逻辑移位,两者左移时⼀样,右移时逻辑移位最⾼位填充的是0,算术移位最⾼位填充的是符号位。2时序逻辑电路--触发器与锁存器2.1.1同步复位D触发器
复位信号在所需时钟边沿才有效,复位操作需要同步于时钟故称作同步复位。代码如下
View Code1 module d_ff2 (3 input clk,4 input rst_n,5 input D,6 output reg Q,7 output O_n8 );9
10 always @(posedge clk)11if(!rst_n)Q<=1'b0;12else Q<=D;13
14 assign Q_n=~Q;15
16 endmoduleRTL级视图
Technology Map Viewer视图如下
2.1.2 异步复位D触发器
将上述语句改为always @(posedge clk or negedge rst_n)即构成异步复位D触发器。只要复位信号有效,输出⽴即复位。很多写法中都采取异步复位模式,后⾯就不在讨论。2.1.3 T触发器代码如下
View Code1 module t_ff2 (3 input clk,4 input rst_n,5 input T,6 output reg Q,7 output Q_n8 );9
10 always @ (posedge clk or negedge rst_n)11if(!rst_n) Q<=1'b0;12else if(T) Q<=~Q;13
14 assign Q_n=~Q;15
16 endmodule
Technology Map View如下
testbench如下
View Code
1 `timescale 1ns/1ns2 module t_ff_tb;3 reg clk,rst_n,T;4 wire Q,Q_n;
5//*************************************** 6//时钟与复位激励7 parameter CLK_PERIOD=20,8 RESET_TIME=10;9 initial clk=0;
10 initial forever #(CLK_PERIOD/2) clk=~clk;11 initial rst_n=0;
12 initial forever #RESET_TIME rst_n=1;13//***************************************14 initial T=0;
15 initial forever #25 T={$random}%2;16 initial #200 $stop;
因篇幅问题不能全部显示,请点此查看更多更全内容