eric2013 发表于 2013-1-25 16:23:53

组合逻辑电路(4)----- 算数运算(加法器 ALU 流水线)


eric2013 发表于 2013-1-25 16:39:09

【例3.1】4位全加器
module adder4(cout,sum,ina,inb,cin);
output sum;
output cout;
input ina,inb;
input cin;
assign {cout,sum}=ina+inb+cin;
endmodule
【例5.11】模为60的BCD码加法计数器
module count60(qout,cout,data,load,cin,reset,clk);
output qout;
output cout;
input data;
input load,cin,clk,reset;
reg qout;
always @(posedge clk)            //clk上升沿时刻计数
begin
if (reset)      qout<=0;      //同步复位
elseif(load)    qout<=data;   //同步置数
elseif(cin)
begin
if(qout==9)      //低位是否为9,是则
begin
qout<=0;          //回0,并判断高位是否为5
if (qout==5)qout<=0;
else
qout<=qout+1;   //高位不为5,则加1
end
else            //低位不为9,则加1
qout<=qout+1;
end
end
assign cout=((qout==8'h59)&cin)?1:0;    //产生进位输出信号
endmodule
【例6.1】加法计数器中的进程
module count(data,clk,reset,load,cout,qout);
output cout;
output qout;
reg qout;
input data;
input clk,reset,load;
always @(posedge clk)         //进程1,always过程块
    begin
if (!reset)    qout= 4'h00;         //同步清0,低电平有效
else if (load)   qout= data;   //同步预置
else      qout=qout + 1;      //加法计数
    end
assign cout=(qout==4'hf)?1:0;      //进程2,用持续赋值产生进位信号
endmodule

eric2013 发表于 2013-1-25 21:43:18

1位半加器
【例7.9】调用门元件实现的1位半加器
module half_add1(a,b,sum,cout);
input a,b;
output sum,cout;
and(cout,a,b);
xor(sum,a,b);
endmodule
【例7.10】数据流方式描述的1位半加器
module half_add2(a,b,sum,cout);
input a,b;
output sum,cout;
assign sum=a^b;
assign cout=a&b;
endmodule
【例7.11】采用行为描述的1位半加器
module half_add3(a,b,sum,cout);
input a,b;
output sum,cout;
reg sum,cout;
always @(a or b)
begin
case ({a,b})                   //真值表描述
2'b00: beginsum=0; cout=0;end
2'b01: beginsum=1; cout=0;end
2'b10: beginsum=1; cout=0;end
2'b11: beginsum=0; cout=1;end
endcase
end
endmodule
【例7.12】采用行为描述的1位半加器
module half_add4(a,b,sum,cout);
input a,b;
output sum,cout;
reg sum,cout;
always @(a or b)
begin
sum= a^b;
cout=a&b;
end
endmodule
【例7.17】混合描述的1位全加器
module full_add5(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
reg cout,m1,m2,m3;            //在always块中被赋值的变量应定义为reg型
wire s1;
xor x1(s1,a,b);                     //调用门元件
always @(a or b or cin)       //always块语句
    begin
m1 = a & b;
m2 = b & cin;
m3 = a & cin;
cout = (m1| m2) | m3;
end
assign sum = s1 ^ cin;      //assign持续赋值语句
endmodule

eric2013 发表于 2013-1-26 09:24:15

【例9.28】用函数实现简单的处理器
module mpc(instr,out);
input instr;                //instr为输入的指令
output out;         //输出结果
reg out;
reg func;
reg op1,op2;          //从指令中提取的两个操作数

function code_add;       //函数的定义
input instr;
reg add_func;
reg code,opr1,opr2;
begin
code=instr;      //输入指令instr的高2位是操作码
opr1=instr;         //输入指令instr的低8位是操作数opr1
case(code)
    2'b00:
begin
add_func=1;
opr2=instr;      //从instr中取第二个操作数
end
    2'b01:
begin
    add_func=0;
   opr2=instr;      //从instr中取第二个操作数
end
    2'b10:
begin
    add_func=1;
    opr2=8'd1;          //第二个操作数取为1,实现+1操作
end
    default:
begin
   add_func=0;
   opr2=8'd1;          //实现-1操作
end
    endcase
code_add={add_func,opr2,opr1};
end
endfunction

always @(instr)
begin
   {func,op2,op1}=code_add(instr);   //调用函数
    if(func==1)out=op1+op2;             //实现两数相加、操作数1加1操作
   else         out=op1-op2;               //实现两数相减、操作数1减1操作
    end
endmodule

eric2013 发表于 2013-1-26 10:00:43

【例10.1】非流水线方式8位全加器
module adder8(cout,sum,ina,inb,cin,clk);
output sum;
output cout;
input ina,inb;
input cin,clk;
reg tempa,tempb,sum;
reg cout;
reg tempc;
always @(posedge clk)
begin
tempa=ina;tempb=inb;tempc=cin;   //输入数据锁存
end
always @(posedge clk)
begin
{cout,sum}=tempa+tempb+tempc;
end
endmodule
【例10.2】4级流水方式的8位全加器
module pipeline(cout,sum,ina,inb,cin,clk);
output sum;
output cout;
input ina,inb;
input cin,clk;
reg tempa,tempb,sum;
reg tempci,firstco,secondco,thirdco,cout;
reg firsts,thirda,thirdb;
reg seconda,secondb,seconds;
reg firsta,firstb,thirds;

always @(posedge clk)
begin
tempa=ina;tempb=inb;tempci=cin;    //输入数据缓存
end
always @(posedge clk)
begin
{firstco,firsts}=tempa+tempb+tempci;
//第一级加(低2位)
firsta=tempa;      //未参加计算的数据缓存
firstb=tempb;
end
always @(posedge clk)
begin
{secondco,seconds}={firsta+firstb+firstco,firsts};
//第二级加(第2、3位相加)
seconda=firsta;      //数据缓存
secondb=firstb;
end
always @(posedge clk)
begin
{thirdco,thirds}={seconda+secondb+secondco,seconds};
//第三级加(第4、5位相加)
thirda=seconda;    //数据缓存
thirdb=secondb;
end
always @(posedge clk)
begin
{cout,sum}={thirda+thirdb+thirdco,thirds};
//第四级加(高两位相加)
end
endmodule

eric2013 发表于 2013-1-26 10:39:49

【例10.3】两个加法器和一个选择器的实现方式
module resource1(sum,a,b,c,d,sel);
parameter size=4;
output sum;
input sel;
input a,b,c,d;
reg sum;
always @(a or b or c or d or sel)
begin
if(sel)sum=a+b;
else    sum=c+d;
end
endmodule
【例10.4】两个选择器和一个加法器的实现方式
module resource2(sum,a,b,c,d,sel);
parameter size=4;
output sum;
input sel;
input a,b,c,d;
reg atemp,btemp;
reg sum;
always @(a or b or c or d or sel)
begin
if(sel)beginatemp=a;btemp=b;end
else    beginatemp=c;btemp=d;end
sum=atemp+btemp;
end
endmo

eric2013 发表于 2013-1-26 11:45:00

【例5.16】用for 语句实现2个8位数相乘
module mult_for(outcome,a,b);
parameter size=8;
input a,b;                   //两个操作数
output outcome;      //结果
reg outcome;
integer i;
always @(a or b)
    begin
outcome=0;
for(i=1; i<=size; i=i+1)      //for语句
if(b)outcome=outcome +(a << (i-1));
    end
endmodule
【例5.17】用repeat实现8位二进制数的乘法
module mult_repeat(outcome,a,b);
parameter size=8;
input a,b;
output outcome;
reg temp_a,outcome;
reg temp_b;
always @(a or b)
begin
outcome=0;
temp_a=a;
temp_b=b;
repeat(size)         //repeat语句,size为循环次数
begin
if(temp_b)      //如果temp_b的最低位为1,就执行下面的加法
outcome=outcome+temp_a;
temp_a=temp_a<<1;      //操作数a左移一位
【例6.6】阶乘运算函数
module funct(clk,n,result,reset);
output result;
input n;
input reset,clk;
reg result;
always @(posedge clk)          //在clk的上升沿时执行运算
begin
if(!reset)result<=0;      //复位
elsebegin
result <= 2 * factorial(n); //调用factorial函数
end
end

function factorial;      //阶乘运算函数定义(注意无端口列表)
input opa;               //函数只能定义输入端,输出端口为函数名本身
reg i;
begin
factorial = opa ? 1 : 0;
for(i= 2; i <= opa; i = i+1)   //该句若要综合通过,opa应赋具体的数值
factorial = i* factorial;       //阶乘运算
end

function factorial;      //阶乘运算函数定义(注意无端口列表)
input opa;               //函数只能定义输入端,输出端口为函数名本身
reg i;
begin
factorial = opa ? 1 : 0;
for(i= 2; i <= opa; i = i+1)   //该句若要综合通过,opa应赋具体的数值
factorial = i* factorial;       //阶乘运算
end
endfunction
endmodule
页: [1]
查看完整版本: 组合逻辑电路(4)----- 算数运算(加法器 ALU 流水线)