用verilog编写16位加法器 乘法器 自动售货机

用verilog编写16位加法器 乘法器 自动售货机
用verilog编写16位加法器 乘法器 自动售货机

Verilog课程实验报告

实验1十六位超前进位加法器

1.1系统设计要求

用超前进位加法器实现一个有符号位的16位加法器,并且考虑溢出的情况

2.1详细设计

根据超前进位加法器的原理Co = G | ( P & Ci ) S = P ^ Ci 设计出4位加法器的子模块,然后通过4个4位加法器的相连来得到十六位的加法器。原理如下图所示。溢出用flag=0表示。

3.1程序

//-------------16位超前进位加法器-----------------

module cla16(a,b,s,flag); //含有a ,b ,输出s ,进位flag 的模块 input [15:0] a,b;//输入a ,b output [16:0] s; //输出 s output reg flag; //进位

FA FA FA

P 0

G 1

P 0G 1

P 2G 2

P 3G 3

C o,3

C o,2

C o,1

C o,0

C i,0

FA FA FA

P 0

G 1

P 0G 1

P 2G 2

P 3G 3

C o,2

C o,1

C o,0

C i,0

o,3

M u l t i p l e x e r

o P 1P 2P 3

Idea: If (P0 and P1 and P2 and P3 = 1)then C o3 = C 0, else “kill” or “generate”.

wire pp4,pp3,pp2,pp1;

wire gg4,gg3,gg2,gg1;

wire [15:0] Cp;

wire [15:0] p,g;

pg i0 (a[15:0],b[15:0],p[15:0],g[15:0]);

add i1 (p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp1,gg1);

add i2 (p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],pp2,gg2);

add i3 (p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],pp3,gg3);

add i4 (p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],pp4,gg4);

add i5 (pp4,pp3,pp2,pp1,gg4,gg3,gg2,gg1,pp5,gg5);

//调用四位加法器模块

add4 l0 (p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],1'b0,Cp[3],Cp[2],Cp[1],Cp[0]);

add4 l1 (p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],Cp[3],Cp[7],Cp[6],Cp[5],Cp[4]);

add4 l2 (p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],Cp[7],Cp[11],Cp[10],Cp[9],Cp[8]);

add4 l3 (p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],Cp[11],Cp[15],Cp[14],Cp[13],Cp[12]); assign s[0]=p[0]^1'b0; //保留位

assign s[1]=p[1]^Cp[0];

assign s[2]=p[2]^Cp[1];

assign s[3]=p[3]^Cp[2];

assign s[4]=p[4]^Cp[3];

assign s[5]=p[5]^Cp[4];

assign s[6]=p[6]^Cp[5];

assign s[7]=p[7]^Cp[6];

assign s[8]=p[8]^Cp[7];

assign s[9]=p[9]^Cp[8];

assign s[10]=p[10]^Cp[9];

assign s[11]=p[11]^Cp[10];

assign s[12]=p[12]^Cp[11];

assign s[13]=p[13]^Cp[12];

assign s[14]=p[14]^Cp[13];

assign s[15]=p[15]^Cp[14];

assign s[16]=pp5|gg5;

//溢出判断模块

always@(a,b,s)

begin

if ((a[15]==1&&b[15]==1&&s[15]==0)||(a[15]==0&&b[15]==0&&s[15]==1)) flag=1'b1;

else

flag=1'b0;

end

endmodule

//4位加法器模块

module add4(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],Co,Cp[3],Cp[2],Cp[1],Cp[0]);

input [3:0]p,g;

output [3:0] Cp;

assign Cp[0]=g[0]|p[0]&Co;

assign Cp[1]=g[1]|p[1]&Cp[0];

assign Cp[2]=g[2]|p[2]&Cp[1];

assign Cp[3]=g[3]|p[3]&Cp[2];

endmodule

//模块间的进位

module add(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp,gg); input [3:0]p,g;

output pp,gg;

assign pp=p[3]&p[2]&p[1]&p[0];

assign gg=g[3]|(p[3]&(g[2]|p[2]&(g[1]|p[1]&g[0]))); endmodule

//进位信号的产生

module pg(a,b,p,g);

input [15:0] a,b;

output [15:0] p,g;

assign p=a^b;

assign g=a&b;

endmodule

4.1测试程序

通过产生一个随机输入a和b,来验证c=a+b。

//16位加法器的测试文件

`timescale 1ns/1ns

`include"./sixteenadder.v"

module sixteenaddertest;

wire [15:0] s;

reg [15:0]a,b;

wire flag;

parameter times=5;

//随机产生一个数,总共产生6次

initial

begin

a={$random}%65536;

b={$random}%65536;

repeat(times)

begin

#100

a={$random}%65536;

b={$random}%65536;

#100 $stop;

end

cla16 cal161(a,b,s,flag);

endmodule

5.1仿真波形

用mudelsim10.0仿真得到的波形如下所示:

如图a=13604,b=24193 s=-27739.s为负数,产生溢出,溢出标位sto=1.当a=-10743,,b=22115.s=11372没有溢出,sto=0.通过这个实验验证了s=a+b,实现了带符号位的加法器。

实验二十六位加减法器

1.1系统设计要求

将加法器和减法器结合到一起,实现带符号位的16位加减法运算,并考虑溢出。

2.1详细设计

在16位加法器的基础上,加上一条判断语句,如果出现减的操作,被减数取反加一,这样就实现了减的运算,用add_sub来表示加减运算符,当add_sub=0时候实现的是减运算,add_sub=1的时候实现的是加运算。

3.1程序

//--------------------16位加减法器------------------------

module cla16(a,b,s); //定义模块包括a,b,s

input [15:0] a,b;//输入a,b

output [16:0] s; //输出s

wire pp4,pp3,pp2,pp1;

wire gg4,gg3,gg2,gg1;

wire [15:0] Cp;

wire [15:0] p,g;

pg i0 (a[15:0],b[15:0],p[15:0],g[15:0]);

add i1 (p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp1,gg1);

add i2 (p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],pp2,gg2);

add i3 (p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],pp3,gg3);

add i4 (p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],pp4,gg4);

add i5 (pp4,pp3,pp2,pp1,gg4,gg3,gg2,gg1,pp5,gg5);

add4 l0 (p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],1'b0,Cp[3],Cp[2],Cp[1],Cp[0]);

add4 l1 (p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],Cp[3],Cp[7],Cp[6],Cp[5],Cp[4]);

add4 l2 (p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],Cp[7],Cp[11],Cp[10],Cp[9],Cp[8]);

add4 l3 (p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],Cp[11],Cp[15],Cp[14],Cp[13],Cp[12]); assign s[0]=p[0]^1'b0;

assign s[1]=p[1]^Cp[0];

assign s[2]=p[2]^Cp[1];

assign s[3]=p[3]^Cp[2];

assign s[4]=p[4]^Cp[3];

assign s[5]=p[5]^Cp[4];

assign s[6]=p[6]^Cp[5];

assign s[7]=p[7]^Cp[6];

assign s[8]=p[8]^Cp[7];

assign s[9]=p[9]^Cp[8];

assign s[10]=p[10]^Cp[9];

assign s[11]=p[11]^Cp[10];

assign s[12]=p[12]^Cp[11];

assign s[13]=p[13]^Cp[12];

assign s[14]=p[14]^Cp[13];

assign s[15]=p[15]^Cp[14];

assign s[16]=pp5|gg5;

endmodule

module add4(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],Co,Cp[3],Cp[2],Cp[1],Cp[0]); input [3:0]p,g;

input Co;

output [3:0] Cp;

assign Cp[0]=g[0]|p[0]&Co;

assign Cp[1]=g[1]|p[1]&Cp[0];

assign Cp[2]=g[2]|p[2]&Cp[1];

assign Cp[3]=g[3]|p[3]&Cp[2];

endmodule

module add(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp,gg);

input [3:0]p,g;

output pp,gg;

assign pp=p[3]&p[2]&p[1]&p[0];

assign gg=g[3]|(p[3]&(g[2]|p[2]&(g[1]|p[1]&g[0])));

endmodule

module pg(a,b,p,g);

input [15:0] a,b;

output [15:0] p,g;

assign p=a^b;

assign g=a&b;

endmodule

//定义加减法器的模块

module addsub(a,b,s,flag,add_sub);

input[15:0]a,b;

input add_sub;

output [15:0] s;

output reg flag;

wire [15:0]b1;

cla16 cla1(a,b1,s);

/* always@(posedge clk)

begin

if(~add_sub)

begin

b1=~b;

b1=b1+1;

else b1=b;

end

*/

assign b1= (add_sub)? b:(~b+1'b1);//判断是否为减操作,为减操作的话是取反加一的运算always@(a,b,s) //判断是否溢出

begin

if

((a[15]==1&&b[15]==1&&add_sub==1&&s[15]==0)||(a[15]==0&&b[15]==0&&add_sub==1&&s[1 5]==1))

flag=1'b1;

else

flag=1'b0;

end

endmodule

4.1测试程序

`timescale 1ns/1ns

`include"./adder_sub.v"

module adder_sub_test;

wire [15:0] s;

reg [15:0]a,b;

reg add_sub;

wire flag;

initial //初始化,输入测试的数据

begin

a=-16'h7851;

b=16'ha432;

add_sub=1;

#100

begin

a=-16'h1233;

b=16'h3211;

add_sub=0;

end

#100

begin

a=16'h0232;

b=16'ha161;

add_sub=1;

#100

begin

a=16'h5632;

b=16'h04a1;

add_sub=0;

end

#100

begin

a=-16'h1234;

b=16'h4525;

add_sub=0;

end

#1000 $stop;

end

addsub addsub1(a,b,s,flag,add_sub);

endmodule

5.1仿真结果

用modelsim10.0仿真,得到的结果如下所示:

当a=-30801 b=-23502,add-sub=1,加操作,s溢出,产生溢出信号flag=1.

当a=-4659 b=12817 add_sub=0,减操作,输出s=-17476,无溢出,flag=0.

当a=562 b=-24223 add_sub=1,加操作,输出s=-23661,无溢出,flag=0.

通过以上的结果分析,此程序实现了带符号位的加减法的功能。

实验三十六位的乘法器

11系统设计要求

实现16*16位的无符号位的乘法器

2.1详细设计

乘法器的硬件电路原理如下

定义16个寄存器,用来存储一行乘操作产生的数据,最后的结果为所有16行相加。

3.1程序

//----------16位乘法器-------------

module mux(clk,rst_n,en,a,b_in,rdy,mux_out);

input clk;//定义时钟

input rst_n;//复位信号

input en;//使能

input[15:0] a,b_in;//输入a,b-in

output rdy;//输出rdy,当结果正确时候为高电平

output[31:0] mux_out;//乘法输出值

reg rdy;

//定义中间的17个寄存器

reg[15:0] mux_reg0 ;

reg[16:0] mux_reg1 ;

reg[17:0] mux_reg2 ;

reg[18:0] mux_reg3 ;

reg[19:0] mux_reg4 ;

reg[20:0] mux_reg5 ;

reg[21:0] mux_reg6 ;

reg[22:0] mux_reg7 ;

reg[23:0] mux_reg8 ;

reg[24:0] mux_reg9 ;

reg[25:0] mux_reg10 ;

reg[26:0] mux_reg11 ;

reg[27:0] mux_reg12 ;

reg[28:0] mux_reg13 ;

reg[29:0] mux_reg14 ;

reg[30:0] mux_reg15 ;

reg[31:0] mux_reg16 ;

always@(rst_n or a or b_in or en) //监视4个变量

begin

if(!rst_n) //复位

begin

rdy <= 1'b0;

mux_reg0 = 16'd0;

mux_reg1 = 17'd0;

mux_reg2 = 18'd0;

mux_reg3 = 19'd0;

mux_reg4 = 20'd0;

mux_reg5 = 21'd0;

mux_reg6 = 22'd0;

mux_reg7 = 23'd0;

mux_reg8 = 24'd0;

mux_reg9 = 25'd0;

mux_reg10 = 26'd0;

mux_reg11 = 27'd0;

mux_reg12 = 28'd0;

mux_reg13 = 29'd0;

mux_reg14 = 30'd0;

mux_reg15 = 31'd0;

mux_reg16 = 32'd0;

end //

else if(en&&rst_n) //开始乘法的运算操作

begin

if(a[0]) mux_reg0 <= b_in; else mux_reg0 <= 16'd0;

if(a[1]) mux_reg1 <= {b_in,mux_reg16[0]}; else mux_reg1 <= 17'd0;

if(a[2]) mux_reg2 <= {b_in,mux_reg16[1:0]}; else mux_reg2 <= 18'd0;

if(a[3]) mux_reg3 <= {b_in,mux_reg16[2:0]}; else mux_reg3 <= 19'd0;

if(a[4]) mux_reg4 <= {b_in,mux_reg16[3:0]}; else mux_reg4 <= 20'd0;

if(a[5]) mux_reg5 <= {b_in,mux_reg16[4:0]}; else mux_reg5 <= 21'd0;

if(a[6]) mux_reg6 <= {b_in,mux_reg16[5:0]}; else mux_reg6 <= 22'd0;

if(a[7]) mux_reg7 <= {b_in,mux_reg16[6:0]}; else mux_reg7 <= 23'd0;

if(a[8]) mux_reg8 <= {b_in,mux_reg16[7:0]}; else mux_reg8 <= 24'd0;

if(a[9]) mux_reg9 <= {b_in,mux_reg16[8:0]}; else mux_reg9 <= 25'd0;

if(a[10]) mux_reg10 <= {b_in,mux_reg16[9:0]}; else mux_reg10 <= 26'd0;

if(a[11]) mux_reg11 <= {b_in,mux_reg16[10:0]}; else mux_reg11 <= 27'd0;

if(a[12]) mux_reg12 <= {b_in,mux_reg16[11:0]}; else mux_reg12 <= 28'd0;

if(a[13]) mux_reg13 <= {b_in,mux_reg16[12:0]}; else mux_reg13 <= 29'd0;

if(a[14]) mux_reg14 <= {b_in,mux_reg16[13:0]}; else mux_reg14 <= 30'd0;

if(a[15]) mux_reg15 <= {b_in,mux_reg16[14:0]}; else mux_reg15 <= 31'd0;

rdy<=1;

end

else

begin

rdy <= 1'b0 ;

end

end

//输出结果为所有寄存器的和

assign mux_out = mux_reg0+mux_reg1+mux_reg2+mux_reg3+mux_reg4+mux_reg5+mux_reg6+mux_reg7+mux_r eg8+mux_reg9+mux_reg10+mux_reg11+mux_reg12+mux_reg13+mux_reg14+mux_reg15;

endmodule

4.1测试程序

`timescale 1ns/1ns;

`include "./mult.v";

module mult_test;

reg[15:0] a,b_in;

wire rdy;

wire[31:0] mux_out;

reg clk,rst_n,en;

initial

begin

clk=0;

forever #50 clk=~clk;

end

initial

begin

rst_n=0;

en=0;

a=16'h1231;

b_in=16'ha231;

#100

begin

rst_n=1;

en=0;

a=16'h2137;

b_in=16'h0142;

end

#100

begin

rst_n=1;

en=1;

a=16'h0234;

b_in=16'h12a7;

end

#100

begin

rst_n=1;

en=1;

a=16'h0012;

b_in=16'ha261;

end

#100

begin

rst_n=0;

en=1;

a=16'h1112;

b_in=16'h0879;

end

#10000 $stop;

end

mux mux1(.clk(clk),.rst_n(rst_n),.en(en),.a(a),.b_in(b_in),.rdy(rdy),.mux_out(mux_out)); endmodule

5.1仿真波形

通过modelsim10.0仿真产生的波形如下所示:

当rst_n=0处于复位状态输出mux_out=0,当rst=1并且使能端en=1时候,乘法器工作。当a=564,b=4775,mux_out=2693100,sto=1,实现了乘的操作,验证了电路实现乘法功能。

实验四自动售货机设计

1.1系统设计要求

自动售货机投入的金钱有50元,10元,5元,1元四种货币。可供选择的商品有7种类型。投入金钱后选择要买的商品,当投入的钱足够时,显示money_enough。并显示出要买的商品,并且找零,当投入的钱不够的时候,通过复位成初始态。具体的要求如下图所示:

2.1详细设计

初始状态下,设投入的money,找零charge,money_enough都为0。投入的四种货币总共有12种情况,用price_all表示。设商品goods有7种,其价格为1,5,10,15,20,30,50,用price表示。Rest为低电平时候,一切初始。在rest为高电平的时候。选择商品,并且投币,当price-all小于price时候,也就是投入的金钱不够,显示money_enough为0,回初始状态。当pirce_all大于price时候,输出选择的商品goods。并且找零。其状态转换图如下:

3.1程序

//——————————————自动售货机代码--------------------------------- module auto_sell(clk,sell,rest,money,charge,goods,money_enough)

input clk,rest;

input [3:0]money; //投入的金钱有12种

input[2:0] sell; //7种商品

output[7:0] charge; //找零

output[2:0] goods; //表示选择的商品

output money_enough; //钱足够的信号

reg money_enough;

reg [2:0]goods;

reg [7:0] charge;

reg [7:0] price,price_all;

always@(posedge clk or negedge rest)

begin

if(!rest)

begin

charge<=8'd0;

goods<=3'd0;

money_enough<=1'b0;

price<=8'd0;

price_all<=8'd0;

end

else

begin

case(money) //4种面值总共12种选择

4'b0001: begin price_all<=8'd1;end

4'b0010: begin price_all<=8'd5;end

4'b0011: begin price_all<=8'd10;end

4'b0100: begin price_all<=8'd50;end

4'b0101: begin price_all<=8'd2;end

4'b0110: begin price_all<=8'd20;end

4'b0111: begin price_all<=8'd100;end

4'b1000: begin price_all<=8'd11;end

4'b1001: begin price_all<=8'd51;end

4'b1010: begin price_all<=8'd15;end

4'b1011: begin price_all<=8'd55;end

4'b1100: begin price_all<=8'd60;end

default: begin price_all<=8'd0; end

endcase

case(sell) //7种商品

3'b001:begin price<=8'd1;end

3'b010:begin price<=8'd5;end

3'b011:begin price<=8'd10;end

3'b100:begin price<=8'd15;end

3'b101:begin price<=8'd20;end

3'b110:begin price<=8'd30;end

3'b111:begin price<=8'd50;end

default:begin price<=8'd0;end

endcase

if (price_all

begin

price<=8'd0;

money_enough<=1'b0;

goods<=3'd0;

charge<=8'd0;

end

else //投入的钱足够

begin

charge<=price_all-price;

money_enough<=1'b1;

case(price) //用goods显示货物被卖出

1: begin goods<=4'b0001;end

5: begin goods<=4'b0010;end

10: begin goods<=4'b0011;end

15: begin goods<=4'b0100;end

20: begin goods<=4'b0101;end

30: begin goods<=4'b0110;end

50: begin goods<=4'b0111;end

endcase

end

end

end

endmodule

4.1测试文件

初始状态rest为0,每隔100ns输入一次数据,总共输入3次。//---------------自动售货机的测试文件-------------

`timescale 1ns/1ns;

`include "./autosells.v"

module autosell_test;

reg clk,rest;

reg [3:0] money;

reg [2:0] sell;

wire [7:0] charge;

wire[2:0] goods;

wire money_enough;

initial

begin

clk=0;

forever #25 clk=~clk;

end

initial

begin //初始状态

rest=1'b0;

money=4'd7;

sell=3'd4;

#100 //投入51块钱买30元的商品

begin

rest=1'b1;

money=4'd9;

sell=3'd6;

end

#100

begin //投入的钱不够的情况

rest=1'b1;

money=4'd5;

sell=3'd7;

end

#100 //投入1块钱,买1块钱的商品

begin

rest=1'b1;

money=4'd1;

sell=3'd1;

end

#10000 $stop;

end

auto_sell

autosell1(.clk(clk),.sell(sell),.rest(rest),.money(money),.charge(charge),.goods(goods),.money_en ough(money_enough));

endmodule

5.1仿真结果

用mudelsim10.0进行仿真得到的仿真图形如下:

如图所示,在money类型为9,选择商品类型为6,对应的总投入的面值pirce-all=51 ,商品6的价格为price=30,显示money_enough为高电平,找零charge为21。在money为5,商品类型为7时候,Price_all=2,price=50.购买商品投入的钱不够,在经过一个clk的money_enough为低电平,在下一个clk上升沿输入商品goods 以及charge都是0。

经过功能验证,所设计的自动售货机实现了所需的要求。

Verilog各种倍分频器设计

module odd_division(clk,rst,count,clk_odd); /*count没必要放在端口中,这里只是为了仿真时观察*/ input clk,rst; output clk_odd; output[3:0] count; reg clk_odd; reg[3:0] count; parameter N = 6; /*6分频* / always @ (posedge clk) if(! rst) begin count <= 1'b0; clk_odd <= 1'b0; end else if ( count < N/2-1) begin count <= count + 1'b1; end else begin count <= 1'b0; clk_odd <= ~clk_odd; end endmodule 奇数倍分频:归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数从零开始,到N-1)/2进行输出时钟翻转,然后经过(N+1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。再者同时进行下降沿触发的模N计数,到和上升沿过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。 module even_division(clk,rst,count1,count2,clk_even); /*count1,count2没必要放在端口中,这

里只是为了仿真时观察*/ input clk,rst; output[3:0] count1,count2; output clk_even; reg[3:0] count1,count2; reg clkA,clkB; wire clk_even,clk_re; parameter N = 5; /*5分频*/ assign clk_re = ~clk; assign clk_even = clkA | clkB; always @(posedge clk) if(! rst) begin count1 <= 1'b0; clkA <= 1'b0; end else if(count1 < (N - 1)) begin count1 <= count1 + 1'b1; /*这里是非阻塞赋值是先执行了下面的IF判断,最后才赋的值。最初看这程序时没注意,想了好半天*/ if(count1 == (N - 1)/2) begin clkA <= ~clkA; end end else begin clkA <= ~clkA;

用Verilog语言实现任意整数分频器

用Verilog语言实现任意整数分频器 分频器是FPGA设计中使用频率非常高的基本设计之一,尽管在目前大部分设计中,广泛使用芯片厂家集成的锁相环资源,如赛灵思(Xilinx)的DLL.来进行时钟的分频,倍频以及相移。但是对于时钟要求不高的基本设计,通过语言进行时钟的分频相移仍然非常流行,首先这种方法可以节省芯片内部的锁相环资源,再者,消耗不多的逻辑单元就可以达到对时钟操作的目的。另一方面,通过语言设计进行时钟分频,可以看出设计者对设计语言的理解程度。因此很多招聘单位在招聘时往往要求应聘者写一个分频器(比如奇数分频)以考核应聘人员的设计水平和理解程度。下面讲讲对各种分频系数进行分频的方法:第一,偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。电路上只需一个D触发器和一个非门即可实现,Q(n+1)=D,D=~Q(n),clk_out=Q(n+1) . 第二,奇数倍分频:奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法: 占空比为非50%的三分频时钟,完全可以通过计数器来实现,如进行三分频,通过待分频时钟上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。即是在计数值在邻近的1和2进行了两次翻转。这样实现的三分频占空比为1/3或者2/3。 module three(clk_in,rst,clk_out); // 三倍频 inputclk_in,rst; output clk_out; reg clk_out; reg [1:0] count; always @(negedgerst or posedgeclk_in) begin if(rst==0) begin count<=0; clk_out<=0; end else begin count<=count+1; if(count==1) clk_out<=~clk_out; else if(count==2) begin clk_out=~clk_out; count<=0; end end end endmodule 仿真图 另一种实现: module div3(CLKIN,CLKOUT,RESETn); //依然是三倍频 inputCLKIN,RESETn;

实验六--Verilog设计分频器计数器电路答案

实验六 Verilog设计分频器/计数器电路 一、实验目的 1、进一步掌握最基本时序电路的实现方法; 2、学习分频器/计数器时序电路程序的编写方法; 3、进一步学习同步和异步时序电路程序的编写方法。 二、实验内容 1、用Verilog设计一个10分频的分频器,要求输入为clock(上升沿有效),reset(低电平复位),输出clockout为4个clock周期的低电平,4个clock周期的高电平),文件命名为fenpinqi10.v。 2、用Verilog设计一异步清零的十进制加法计数器,要求输入为时钟端CLK(上升沿)和异步清除端CLR(高电平复位),输出为进位端C和4位计数输出端Q,文件命名为couter10.v。 3、用Verilog设计8位同步二进制加减法计数器,输入为时钟端CLK(上升沿有效)和异步清除端CLR(低电平有效),加减控制端UPDOWN,当UPDOWN为1时执行加法计数,为0时执行减法计数;输出为进位端C和8位计数输出端Q,文件命名为couter8.v。 4、用VERILOG设计一可变模数计数器,设计要求:令输入信号M1和M0控制计数模,当M1M0=00时为模18加法计数器;M1M0=01时为模4加法计数器;当M1M0=10时为模12加法计数器;M1M0=11时为模6加法计数器,输入clk上升沿有效,文件命名为mcout5.v。 5、VerilogHDL设计有时钟时能的两位十进制计数器,有时钟使能的两位十进制计数器的元件符号如图所示,CLK是时钟输入端,上升沿有效;ENA是时钟使能控制输入端,高电平有效,当ENA=1时,时钟CLK才能输入;CLR是复位输入端,高电平有效,异步清零;Q[3..0]是计数器低4位状态输出端,Q[7..0]是高4位状态输出端;COUT是进位输出端。 三、实验步骤 实验一:分频器 1、建立工程

verilogHDL分频器(奇数分频和偶数分频)

module clk_div( //-----------input----------- iCLK, div, //-----------output---------- oCLK ); //-----------input----------- parameter WIDE=14; input iCLK; input[WIDE-1:0]div; //-----------output----------- output oCLK; wire oCLK_odd; wire oCLK_even; assign oCLK=div[0]?oCLK_odd:oCLK_even; div_odd DUTo (.iCLK(iCLK),.oCLK(oCLK_odd),.div(div)); div_even DUTe (.iCLK(iCLK),.oCLK(oCLK_even),.div(div)); endmodule // odd module div_odd( //--------input-------- iCLK, div, //--------output-------- oCLK ); //--------input-------- parameter WIDE=14; input iCLK; input[WIDE-1:0]div; //--------output-------- output oCLK; reg outCLK;

/* =========================== solve 1 =========================== reg cout; reg[WIDE-1:0] cnt; initial cnt=0; wire inCLK; reg cc; initial cc=0; always @(posedge cout) cc<=~cc; assign inCLK = iCLK^cc; always @(posedge inCLK) begin if(cnt<(div[WIDE-1:1])) begin cnt<=cnt+1; cout<=1'b0; end else begin cnt<=0; cout<=1'b1; end end always @(negedge iCLK) outCLK <= cout; assign oCLK=cc; */ //======================== //solve 2 //======================== reg[WIDE-1:0] cnt_a; initial cnt_a=0; reg[WIDE-1:0] cnt_b; initial cnt_b=0; reg cout_a;

分频器的verilog hdl语言

分频器的verilog HDL描述(转) 分频器,在许多涉及时序的电路设计中都会用到,在这里,我转载某位高人的文章,关于分频器的设计 偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。 module odd_division(clk,rst,count,clk_odd); input clk,rst; output clk_odd; output[3:0] count; reg clk_odd; reg[3:0] count; parameter N = 6; always @ (posedge clk) if(! rst) begin count <= 1'b0; clk_odd <= 1'b0; end else if ( count < N/2-1) begin count <= count + 1'b1; end else begin

clk_odd <= ~clk_odd; end endmodule 奇数倍分频:归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数从零开始,到(N-1)/2进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。再者同时进行下降沿触发的模N 计数,到和上升沿过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。 module even_division(clk,rst,count1,count2,clk_even); input clk,rst; output[3:0] count1,count2; output clk_even; reg[3:0] count1,count2; reg clkA,clkB; wire clk_even; parameter N = 5; assign clk_re = ~clk; assign clk_even = clkA | clkB; always @(posedge clk) if(! rst) begin count1 <= 1'b0; clkA <= 1'b0; end else

任意分频Verilog实现

1. 偶数倍(2N)分频 使用一模N计数器模块即可实现,即每当模N计数器上升沿从0开始计数至N-1时,输出时钟进行翻转, 同时给计数器一复位信号使之从0开始重新计数,以此循环即可。偶数倍分频原理示意图见图1。 2. 奇数倍(2N+1)分频 (1)占空比为X/(2N+1)或(2N+1-X)/(2N+1)分频,用模(2N+1)计数器模块可以实现。取0至2N-1之间一数值X(0,当计数器时钟上升沿从0开始计数到X值时输出时钟翻转一次,在计数器继续计数达到2N 时,输出时钟再次翻转并对计数器置一复位信号,使之从0开始重新计数,即可实现。 (2)占空比为50%的分频,设计思想如下:基于(1)中占空比为非50%的输出时钟在输入时钟的上升沿 触发翻转;若在同一个输入时钟周期内,此计数器的两次输出时钟翻转分别在与(1)中对应的下降沿触发翻转,输出的时钟与(1)中输出的时钟进行逻辑或,即可得到占空比为50%的奇数倍分频时钟。当然其 输出端再与偶数倍分频器串接则可以实现偶数倍分频。奇数倍分频原理示意图见图2。(这也是许多公司常出的面试题,^_^,是不是很简单?) 3. N-0.5倍分频 采用模N计数器可以实现。具体如下:计数器从0开始上升沿计数,计数达到N-1上升沿时,输出时钟需翻转,由于分频值为N-0.5,所以在时钟翻转后经历0.5个周期时,计数器输出时钟必须进行再次翻转,即当 CLK为下降沿时计数器的输入端应为上升沿脉冲,使计数器计数达到N而复位为0重新开始计数同时输出时钟翻转。这个过程所要做的就是对CLK进行适当的变换,使之送给计数器的触发时钟每经历N-0.5个周期就翻转一次。N-0.5倍:取N=3,分频原理示意图见图3。 对于任意的N+A/B倍分频(N、A、B∈Z,A≦B) 分别设计一个分频值为N和分频值N+1的整数分频器,采用脉冲计数来控制单位时间内两个分频器出现 的次数,从而获得所需要的小数分频值。可以采取如下方法来计算个子出现的频率: 设N出现的频率为a,则N×a+(N+1)×(B-a)=N×B+A 求解a=B-A; 所以N+1出现的频率为 A.例如实现7+2/5分频,取a为3,即7×3+8×2就可以实现。但是由于这种小数分频输出的时钟脉冲抖动很大, 现实中很少使用。 通常实现偶数的分频比较容易,以十分频为例: always @( posedge clk or posedge reset) if(reset) begin k<=0; clk_10<=0; end else if(k==4) begin k<=0;

实验六Verilog设计分频器计数器电路答案

实验六V e r i l o g设计分频器/计数器电路 一、实验目的 1、进一步掌握最基本时序电路的实现方法; 2、学习分频器/计数器时序电路程序的编写方法; 3、进一步学习同步和异步时序电路程序的编写方法。 二、实验内容 1、用Verilog设计一个10分频的分频器,要求输入为clock(上升沿有效),reset(低电平复位),输出clockout为4个clock周期的低电平,4个clock 周期的高电平),文件命名为。 2、用Verilog设计一异步清零的十进制加法计数器,要求输入为时钟端CLK (上升沿)和异步清除端CLR(高电平复位),输出为进位端C和4位计数输出端Q,文件命名为。 3、用Verilog设计8位同步二进制加减法计数器,输入为时钟端CLK(上升沿有效)和异步清除端CLR(低电平有效),加减控制端UPDOWN,当UPDOWN 为1时执行加法计数,为0时执行减法计数;输出为进位端C和8位计数输出端Q,文件命名为。 4、用VERILOG设计一可变模数计数器,设计要求:令输入信号M1和M0控制计数模,当M1M0=00时为模18加法计数器;M1M0=01时为模4加法计数器;当M1M0=10时为模12加法计数器;M1M0=11时为模6加法计数器,输入clk 上升沿有效,文件命名为。 5、VerilogHDL设计有时钟时能的两位十进制计数器,有时钟使能的两位十进制计数器的元件符号如图所示,CLK是时钟输入端,上升沿有效;ENA是

时钟使能控制输入端,高电平有效,当ENA=1时,时钟CLK才能输入;CLR 是复位输入端,高电平有效,异步清零;Q[3..0]是计数器低4位状态输出端,Q[7..0]是高4位状态输出端;COUT是进位输出端。 三、实验步骤 实验一:分频器 1、建立工程 2、创建Verilog HDL文件 3、输入10分频器程序代码并保存 4、进行综合编译 5、新建波形文件 6、导入引脚 7、设置信号源并保存 8、生成网表 9、功能仿真 10、仿真结果分析 由仿真结果可以看出clockout输出5个clock周期的低电平和5个clock 的高电平达到10分频的效果,设计正确。 实验二:十进制加法计数器(异步清零) 1、建立工程 2、创建Verilog HDL文件 3、输入加法计数器代码并保存 4、进行综合编译 5、新建波形文件 6、导入引脚 7、设置信号源并保存 8、生成网表 9、功能仿真 10、仿真结果分析

Verilog分频器设计

Verilog分频器设计 module adder(clk,z); output z; reg q; reg z; always@(posedge clk) begin if(q%9==0) z<=q; else q=q+1; end endmodule module counter9(clk,datein,z); output z; input clk; input datein; reg z; reg[3:0] q; always@(posedge clk) begin q<=q+1; if (q==4'b1001) begin q<=4'b0000; z<=datein; end end endmodule

2008-11-04 19:58 分频器是FPGA设计中使用频率非常高的基本单元之一。尽管目前在大部分设计中还广泛使用集成锁相环(如altera的PLL,Xilinx的DLL)来进行时钟的分频、倍频以及相移设计,但是,对于时钟要求不太严格的设计,通过自主设计进行时钟分频的实现方法仍然非常流行。首先这种方法可以节省锁相环资源,再者,这种方式只消耗不多的逻辑单元就可以达到对时钟操作的目的。偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。 module odd_division(clk,rst,count,clk_odd); /*count没必要放在端口中,这里只是为了仿真时观察*/ input clk,rst; output clk_odd; output[3:0] count; reg clk_odd; reg[3:0] count; parameter N = 6; /*6分频* / always @ (posedge clk) if(! rst) begin count <= 1'b0; clk_odd <= 1'b0; end else if ( count < N/2-1) begin count <= count + 1'b1; end else begin count <= 1'b0; clk_odd <= ~clk_odd;

用verilog实现任意倍分频器的方法

用verilog语言写的任意整数的分频器 占空比:对于一串理想的脉冲序列中(如方波),正脉冲的持续时间与脉冲总周期的比值,叫做这个方波的占空比。 分频分为奇分频和偶分频 第一,偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。 第二:奇数倍分频:奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法:首先,完全可以通过计数器来实现,如进行三分频,通过待分频时钟上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。即是在计数值在邻近的1和2进行了两次翻转。这样实现的三分频占空比为1/3或者2/3。如果要实现占空比为50%的三分频时钟,可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行三分频,然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。这种方法可以实现任意的奇数分频。归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。另外一种方法:对进行奇数倍n分频时钟,首先进行n/2分频(带小数,即等于(n-1)/2+0.5),然后再进行二分频得到。得到占空比为50%的奇数倍分频。 下面讲讲进行小数分频的设计方法: 第三,小数分频:首先讲讲如何进行n+0.5分频,这种分频需要对输入时钟进行操作。基本的设计思想:对于进行n+0.5分频,首先进行模n的计数,在计数到n-1时,输出时钟赋为‘1’,回到计数0时,又赋为0,因此,可以知道,当计数值为n-1时,输出时钟才为1,因此,只要保持计数值n-1为半个输入时钟周期,即实现了n+0.5分频时钟,因此保持n-1为半个时钟周期即是一个难点。从中可以发现,因为计数器是通过时钟上升沿计数,因此可以在计数为n- 1时对计数触发时钟进行翻转,那么时钟的下降沿变成了上升沿。即在计数值为n-1期间的时钟下降沿变成了上升沿,则计数值n-1只保持了半个时钟周期,由于时钟翻转下降沿变成上升沿,因此计数值变为0。因此,每产生一个n+0.5分频时钟的周期,触发时钟都是要翻转一次。设计思路如下:

Verilog程序代码集

1.全加器 Sum=A⊕B⊕Cin Count=AB+Cin(A+B) ①数据流 module adder(a,b,Cin,Sum,Count); input [2:0]a,b; input Cin; output [2:0] Sum; output Count; assign {Count,Sum}=a+b+Cin; endmodule ②行为描述always语句 module adder(a,b,c,Cin,Sum,Count); input [4:0] a,b; input Cin; output reg [4:0] Sum; output reg Count; reg T1,T2,T3; always@(a or b or Cin) begin Sum=a^b^Cin; T1=A&B; T2=Cin&A; T3=Cin&B; Count=T1|T2|T3; end endmodule ③结构体 module adder (a,b,Cin,Sum,Count);input a,b,Cin; output Sum,Count; Xor a1(s1,a1,b); Xor a2(Sum,s1,Cin); and a3(T1,a,b); or a4(T2,a,b); and a5(T3,Cin,T2); or a6(Count,T1,T3); Endmodule 2.数值比较器 ①判断两值是否相等 module compare(a,b,equal); input [7:0] a,b; output equal; assign equal=(a==b)?|0; ②谁大谁输出 module compare(a,b,out); input [7:0] a,b; output reg[7:0] out; always@(a or b) begin if (a>b) out<=a; else if (a==b) out<=a; else out<=b; end endmodule ③输出参数 module compare(a.b.xgy,xsy,xey); input [7:0] x,y; output reg xgy,xsy,xey; always@(x or y) begin if (x==y) xey=1; else xey=0; if (x>y) begin xgy=1;xsy=0;end else if (x

Verilog HDL4 7 分频代码

四分频 module quarter_clk(reset,clk_in,clk_out); input clk_in,reset; output clk_out; reg clk_out; reg [4:0]count; always@(posedge clk_in) begin if(!reset) clk_out=0; else if (count<1) begin count<=count+1; end else begin count<=0; clk_out=~clk_out; end end endmodule 仿真 `define clk_cycle 50 module test_quarter_clk; reg clk,reset; wire clk_out; always #`clk_cycle clk=~clk; initial begin clk=0; reset=1; #100 reset=0; #100 reset=1; #10000 $stop; end quarter_clk quarter_clk1(reset,clk,clk_out); endmodule

7分频 module div7(rst,clk,cout1,cout2,cout); input clk,rst; output cout1,cout2,cout; reg [2:0] m,n; wire cout; reg cout1,cout2; assign cout=cout1|cout2; always @(posedge clk) begin if(rst) begin cout1<=0;m<=0;end else if(!rst) begin if(m==6) begin m<=0;end else m<=m+1; if(m==2) cout1=~cout1; else if(m==5) c out1=~cout1; end end always @(negedge clk) begin if(rst) begin cout2<=0;n<=0;end else if(!rst) begin if(n==6) begin n<=0;end else n<=n+1; if(n==2) cout2=~cout2; else if(n==5) cout2=~cout2; end end Endmodule 仿真 `timescale 1ns / 1ps `define clk_cycle 50 module qii; reg clk,rst; wire cout1,cout2,cout; always #`clk_cycle clk=~clk; initial begin clk=0; rst=1;

数控分频verilog

EDA实验报告 数控分频器 实验目的 1.掌握数控分频器的工作原理并能够用virlog语言编写代码,熟悉EDA6000实验箱的 使用方法。 2.进一步熟悉quartusII建立程序编译、仿真及下载的操作流程并学会数控分频器的 V erilog硬件设计 实验步骤 1.新建V erilog工程,编写代码并保存至与模块名对应的文件夹。注意:项目应存为系 统盘以外的盘内,路径中不含中文字符。 2.编译程序,编译无误后,在【tools】里面选择RTL视,观察电路结构。 3.新建波形文件进行仿真。保存时要和源程序存放在同一目录下。设置好输入波形参数 后,开始仿真。在仿真后输入输出波形中观察逻辑关系是否正确。 4.将实验箱和PC合理连接起来。打开EDA6000软件,设置好芯片类型为ACEX1K (EP1K30TC144-3),载入模式9. 5.根据EDA6000界面内管脚对应芯片的实际管脚在QUARTUSII里面设定 管脚号并检查无误。 6.将程序下载至FPGA内,并在EDA6000软件界面内进行验证测试。 程序代码1 /////偶数分频占空比50%,奇数分频没做要求////////// module divider(clk,data,fout); //数控分频器 input clk; //时钟输入 input[7:0]data; //预置数控分频数(对应的十进制数) output fout; //分频输出 reg [7:0]m; reg cout1; always @(posedge clk) begin if(m==data-1)begin m<=0;cout1=~cout1;end else m<=m+1; if(m==(data-1)/2)begin cout1=~cout1;end else begin cout1<=cout1;end end assign fout=cout1; endmodule

VERILOG 分频原理

VERILOG 分频原理 众所周知,分频器是FPGA设计中使用频率非常高的基本设计之一,尽管在目前大部分设计中,广泛使用芯片厂家集成的锁相环资源,如altera 的PLL,Xilinx的DLL.来进行时钟的分频,倍频以及相移。但是对于时钟要求不高的基本设计,通过语言进行时钟的分频相移仍然非常流行,首先这种方法可以节省芯片内部的锁相环资源,再者,消耗不多的逻辑单元就可以达到对时钟操作的目的。另一方面,通过语言设计进行时钟分频,可以看出设计者对设计语言的理解程度。因此很多招聘单位在招聘时往往要求应聘者写一个分频器(比如奇数分频)以考核应聘人员的设计水平和理解程度。下面讲讲对各种分频系数进行分频的方法: 第一,偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。 第二,奇数倍分频:奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法: 首先,完全可以通过计数器来实现,如进行三分频,通过待分频时钟上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。即是在计数值在邻近的1和2进行了两次翻转。这样实现的三分频占空比为1/3或者2/3。如果要实现占空比为50%的三分频时钟,可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行三分频,然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。这种方法可以实现任意的奇数分频。归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。 另外一种方法:对进行奇数倍n分频时钟,首先进行n/2分频(带小数,即等于 (n-1)/2+0.5),然后再进行二分频得到。得到占空比为50%的奇数倍分频。下面讲讲进行小数分频的设计方法

verilog奇偶分频器的实现

任意分频的verilog语言实现 现来说说分频原理吧,原理通了,什么都好办了。 1. 偶数倍(2N)分频 使用一模N计数器模块即可实现,即每当模N计数器上升沿从0开始计数至N-1时,输出时钟进行翻转,同时给计数器一复位信号使之从0开始重新计数,以此循环即可。偶数倍分频原理示意图见图1。 2. 奇数倍(2N+1)分频 (1)占空比为X/(2N+1)或(2N+1-X)/(2N+1)分频,用模(2N+1)计数器模块可以实现。取0至2N-1之间一数值X(0,当计数器时钟上升沿从0开始计数到X值时输出时钟翻转一次,在计数器继续计数达到2N 时,输出时钟再次翻转并对计数器置一复位信号,使之从0开始重新计数,即可实现。 (2)占空比为50%的分频,设计思想如下:基于(1)中占空比为非50%的输出时钟在输入时钟的上升沿触发翻转;若在同一个输入时钟周期内,此计数器的两次输出时钟翻转分别在与(1)中对应的下降沿触发翻转,输出的时钟与(1)中输出的时钟进行逻辑或,即可得到占空比为50%的奇数倍分频时钟。当然其输出端再与偶数倍分频器串接则可以实现偶数倍分频。奇数倍分频原理示意图见图2。(这也是许多公司常出的面试题,^_^,是不是很简单?) 3. N-0.5倍分频 采用模N计数器可以实现。具体如下:计数器从0开始上升沿计数,计数达到 N-1上升沿时,输出时钟需翻转,由于分频值为N-0.5,所以在时钟翻转后经历0.5个周期时,计数器输出时钟必须进行再次翻转,即当CLK为下降沿时计数器的输入端应为上升沿脉冲,使计数器计数达到N而复位为0重新开始计数同时输出时钟翻转。这个过程所要做的就是对CLK进行适当的变换,使之送给计数器的触发时钟每经历N-0.5个周期就翻转一次。N-0.5倍:取N=3,分频原理示意图见图3。 对于任意的N+A/B倍分频(N、A、B∈Z,A≦B)

N倍奇数分频器.(Verilog)

标签:Verilog分频器 N倍奇数分频器.(V erilog) N_odd_divider.v / Verilog module N_odd_divider ( input i_clk, input rst_n, output o_clk ); parameter N = N_odd; // 设置奇数(除1外)倍分频parameter M = ?; // M="N/2" // bit_of_N: N_odd的二进制位宽 reg [(bit_of_N - 1):0] cnt_p; // 上升沿计数单位 reg [(bit_of_N - 1):0] cnt_n; // 下降沿计数单位 reg clk_p; // 上升沿时钟 reg clk_n; // 下降沿时钟 assign o_clk = clk_n & clk_p; // 按位与(作用:掩码) // 上升沿计数器: 0~(N-1) always @ (posedge i_clk or negedge rst_n)

begin if (!rst_n) cnt_p <= 0; else begin if (cnt_p == N-1) cnt_p <= 0; else cnt_p <= cnt_p + 1'b1; end end // 生成上升沿时钟 // 0~(N>>1) ↑ -> 1;((N/2)+1)~(N-1) ↑ -> 0 always @ (posedge i_clk or negedge rst_n) begin if (!rst_n) clk_p <= 0; else begin if (cnt_p <= M) // 0 ~ (N/2) clk_p <= 1; else

Verilog HDL分频器设计报告

2011-2012第二学期专业选修课HDL语言应用与设计课程设计报告 Veriog HDL 分 频 器 设 计 报 告 设计时间:2012.4 班级:信科09-2 姓名:程雷 学号:08093534 指导老师:王冠军

一、设计目的和要求: 目的: 1、学会使用Quantus软件(编译、仿真等),并利用它进行设计一些简单的数字电路; 2、利用实验室提供的FPGA/CPLD实验箱,结合Quantus II软件实现分频器 的功能。 要求:分频器可以简单实用的设置分频系数。 二、实验器件和环境 实验室提供的FPGA/CPLD实验箱,PC机和Quantus II软件。 三、设计方案和源程序代码 首先分析分频器要实现的功能,然后确定他的基本结构,因为分频器的基本功能要使其分频的的功能可以控制,所以要有控制使能端口;分频器的分频系数可以自由选择,所以应有分频系数设置使能端;分频之后可以输出分频之后的频率,所以应该有输出端口。本本设计只是任意整数分频器。 1、偶数倍分频:偶数倍分频,通过计数器计数是完全可以实现的。如进行N 倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。 原理:比如4分频,需要一个模4的计数器,占空比50%,计数为0~3循环,当计数到一半时,即计数输出cnt<2时翻转。 例题代码如下: //四分频 module div4(clk,rst_n,o_clk); input clk,rst_n; output o_clk; reg o_clk; reg [1:0]cnt; always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt<=0; else if(cnt==3) cnt<=0; else cnt<=cnt+1; end always @(posedge clk or negedge rst_n) begin if(!rst_n)

Verilog分频器设计

实验5 分频器设计 【实验目的】 在平时的应用中,经常会遇到一些需要特殊时钟的要求,这时就需要用到标准时钟,并且将它分频为我们想要的时钟,在本次实验中,将设计不同分频的分频器以满足设计的时钟要求。 【实验思考】 总的来说,分频器可以大致分为两种分频器,一种是奇数分频,还有一种则是偶数分频。然后是设计其占空比。 一、偶数分频 若给定一个偶数2N,要用标准时钟生成2N分频,首先我们要建立一个计数器,其模可为2N,也可为N,若为2N,则可以设置输出小雨N+1作电平从0到1或者相反,这样可以控制其占空比;若计数器模为N,则计数器计完一个循环便使输出翻转即可,这样得到了占空比为50%的输出,但其速度要比前者快一倍。以下以六分频为例编写一个占空比为50%的分频器。 【实验代码】 module jishuqi(Q,clk); input clk; output[2:0]Q; reg[2:0]Q; initial Q=3'b000; always@(posedge clk) begin Q=Q+1'b1; if(Q[0]) if(Q[1]) if(!Q[2]) Q=0;//模为3的计数器 end endmodule module feng61(clk,clo); input clk; output clo; wire [2:0]E; reg clo; initial clo=0; jishuqi u(E,clk) ; always@(E) begin if(!E[2]) if(!E[1])

if(!E[0]) begin clo=clo+1'b1;end end //偶数分频时,只需要计数器计到N/2时将待分频翻转即可,其中N单单取上升沿或者下降沿 endmodule 从仿真结果中可以看到除了初始的时钟显示不完整,其余的均为六分频 其rtl网表如下:

verilog实验四分频器

Verilog HDL实验报告 Verilog 实验报告 题目:分频器 系部名称:通信工程 专业名称:通信工程 班级: 班内序号: 学生姓名: 时间:2010.12.12

一、实验要求: 设计一个将10MHz时钟分频为500KHz的时钟,有复位端; 二、实验内容: 源文件 module fenpin(clr,a,b); input a; input clr; output b; integer i=0; reg b; always @(negedge clr or posedge a) if(!clr) begin b=0; i=0; end else begin i=i+1; if(i==11) begin b=~b; i=1; end end endmodule 测试文件 `timescale 10ns/100ps module fenpin_test; reg a; reg clr; wire b; fenpin u1(clr,a,b); initial begin $monitor($time,"clr=%b,a=%b,b=%b",clr,a,b); clr=1'b0; a=1'b0;

#5 clr=1'b1; end always #5 a=~a; endmodule # 0clr=0,a=0,b=0 # 5clr=1,a=1,b=0 # 10clr=1,a=0,b=0 # 15clr=1,a=1,b=0 # 20clr=1,a=0,b=0 # 25clr=1,a=1,b=0 # 30clr=1,a=0,b=0 # 35clr=1,a=1,b=0 # 40clr=1,a=0,b=0 # 45clr=1,a=1,b=0 # 50clr=1,a=0,b=0 # 55clr=1,a=1,b=0 # 60clr=1,a=0,b=0 # 65clr=1,a=1,b=0 # 70clr=1,a=0,b=0 # 75clr=1,a=1,b=0 # 80clr=1,a=0,b=0 # 85clr=1,a=1,b=0 # 90clr=1,a=0,b=0 # 95clr=1,a=1,b=1 # 100clr=1,a=0,b=1 # 105clr=1,a=1,b=1 # 110clr=1,a=0,b=1 # 115clr=1,a=1,b=1 # 120clr=1,a=0,b=1 # 125clr=1,a=1,b=1 # 130clr=1,a=0,b=1 # 135clr=1,a=1,b=1

相关主题
相关文档
最新文档