云计算百科
云计算领域专业知识百科平台

8bit数据差值与最小值计算实战

根据输入信号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

超前进位加法器

赞(0)
未经允许不得转载:网硕互联帮助中心 » 8bit数据差值与最小值计算实战
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!