根据输入信号a,b的大小关系,求解两个数的差值:输入信号a,b为8bit位宽的无符号数。如果a>b,则输出a-b,如果a≤b,则输出b-a。
`timescale 1ns/1ns
module data_minus(
input clk,
input rst_n,
input [7:0]a,
input [7:0]b,
output reg [8:0]c
);
always@(posedge clk or negedge rst_n) begin
if(rst_n == 'd0) begin
c<='d0;
end
else if(a>b) begin
c<=a-b;
end
else begin
c<= b-a;
end
end
endmodule
使用generate…for语句简化代码
genvar i; //声明循环变量为非负整数
generate
for(i = 0; i < 8; i = i + 1) //循环条件
begin : bit_reverse //begin…end块中为待生成的代码原型
assign data_out[i] = data_in[7 – i];
end
endgenerate
在begin之后的bit_reverse是需要的,表示该generate…for语句块的名称,可以根据需要修改。特别需要注意的是,即使只有一个语句,也需要使用begin…end。同时需要使用endgenerate表示结束。
(1)generate for的循环变量必须用genvar声明,for的变量可以用reg、integer整数等多种类型声明;
(2)for只能用在always块里面,generate for可以做assign赋值,用always块话always写在generate for里;
(3)generate for后面必须给这个循环起一个名字,for不需要;
(4)generate for还可以用于例化模块;
在数字芯片设计中,通常把完成特定功能且相对独立的代码编写成子模块,在需要的时候再在主模块中例化使用,以提高代码的可复用性和设计的层次性,方便后续的修改。
请编写一个子模块,将输入两个8bit位宽的变量data_a,data_b,并输出data_a,data_b之中较小的数。并在主模块中例化,实现输出三个8bit输入信号的最小值的功能。
`timescale 1ns/1ns
module main_mod(
input clk,
input rst_n,
input [7:0]a,
input [7:0]b,
input [7:0]c,
output [7:0]d
);
wire [7:0]min1,min2;
min2 minab(
.clk(clk),
.rst_n(rst_n),
.a(a),
.b(b),
.c(min1)
);
min2 minac(
.clk(clk),
.rst_n(rst_n),
.a(a),
.b(c),
.c(min2)
);
min2 min3(
.clk(clk),
.rst_n(rst_n),
.a(min1),
.b(min2),
.c(d)
);
endmodule
module min2(
input wire clk,
input wire rst_n,
input wire [7:0] a,
input wire [7:0]b,
output reg [7:0]c
);
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
c <= 'd0;
end
else if(a<b) begin
c<= a;
end
else if(a>b) begin
c<= b;
end
else c<='d0;
end
endmodule
在数字芯片设计中,经常把实现特定功能的模块编写成函数,在需要的时候再在主模块中调用,以提高代码的复用性和提高设计的层次,分别后续的修改。
请用函数实现一个4bit数据大小端转换的功能。实现对两个不同的输入分别转换并输出。
在Verilog HDL中,函数的声明由关键字function开始,endfunction结束。对于函数中的语句需要用begin…end包含,即使只有一句。函数的声明模板如下:
function [range-1:0] function_name ;
input_declaration ;
other_declaration ;
procedural_statement ;
endfunction
函数在声明时,会隐式的声明一个宽度为 range、 名字为 function_id 的寄存器变量,函数的返回值通过这个变量进行传递。当该寄存器变量没有指定位宽时,默认位宽为 1。然后进行输入变量的声明和其它声明。
函数通过指明函数名与输入变量进行调用。函数结束时,返回值被传递到调用处。
函数调用格式如下:
function_name(input1, input2, …);
通过函数名调用函数,并在参数列表中填入输入参数。
要实现大小端转换,即将输入数值的最高位赋予输出的最低位,次高位赋予次低位,依次类推即可。
function [3:0] data_rev;
input [3:0] data_in;
begin
data_rev[0] = data_in[3];
data_rev[1] = data_in[2];
data_rev[2] = data_in[1];
data_rev[3] = data_in[0];
end
endfunction
函数编写完成,则可以在多个位置进行调用,输入不同的参数,实现对不同数据的操作
`timescale 1ns/1ns
module function_mod(
input [3:0]a,
input [3:0]b,
output [3:0]c,
output [3:0]d
);
assign c = data_rev(a);
assign d = data_rev(b);
function [3:0] data_rev;
input [3:0] data_in;
begin
data_rev[0] = data_in[3];
data_rev[1] = data_in[2];
data_rev[2] = data_in[1];
data_rev[3] = data_in[0];
end
endfunction
endmodule
某4位数值比较器的功能表如下。
请用Verilog语言采用门级描述方式,实现此4位数值比较器

`timescale 1ns/1ns
module comparator_4(
input[3:0] A ,
input [3:0]B ,
output wireY2 , //A>B
output wire Y1 , //A=B
output wire Y0 //A<B
);
assign Y2 = ((A[3]>B[3]) || ((A[3]==B[3] && A[2]>B[2])) || (A[3]==B[3] && A[2]==B[2] && A[1]>B[1]) || (A[3]==B[3] && A[2]==B[2] && A[1]==B[1] && A[0] > B[0]) ) ? 1:0;
assign Y1 = (A[3]==B[3] && A[2]==B[2] && A[1]==B[1] && A[0]==B[0]) ? 1:0;
assign Y0 = ((A[3]<B[3]) || ((A[3]==B[3] && A[2]<B[2])) || (A[3]==B[3] && A[2]==B[2] && A[1]<B[1]) || (A[3]==B[3] && A[2]==B[2] && A[1]==B[1] && A[0] < B[0]) ) ? 1:0;
endmodule
超前进位加法器
网硕互联帮助中心



评论前必须登录!
注册