使用函数实现数据大小端转换
题目描述
在数字芯片设计中,经常把实现特定功能的模块编写成函数,在需要的时候再在主模块中调用,以提高代码的复用性和提高设计的层次,分别后续的修改。
请用函数实现一个4bit数据大小端转换的功能。实现对两个不同的输入分别转换并输出。
接口的信号图如下:
`timescale 1ns/1ns
module function_mod(
input clk,
input rst_n,
input [3:0]a,
input [3:0]b,
output [3:0]c,
output [3:0]d
);
reg [3:0] c_reg;
reg [3:0] d_reg;
always@(*)
begin
if(!rst_n)
begin
c_reg = 4'b0;
d_reg = 4'b0;
end
else
begin
c_reg = conversion(a);
d_reg = conversion(b);
end
end
assign c = c_reg;
assign d = d_reg;
function [3:0] conversion;
input [3:0] data_in;
integer i;
begin
for(i = 0; i <= 3; i = i + 1)
conversion[i] = data_in[ 3 - i];
end
endfunction
endmodule
知识点
在 Verilog 中,可以利用任务(关键字为 task)或函数(关键字为 function),将重复性的行为级设计进行提取,并在多个地方调用,来避免重复代码的多次编写,使代码更加的简洁、易懂。
函数只能在模块中定义,位置任意,并在模块的任何地方引用,作用范围也局限于此模块。函数主要有以下几个特点:
- 不含任何延迟、时序或时序控制逻辑。–只能是组合逻辑
- 至少有一个输入变量。
- 只有一个返回值(返回值的变量就是函数名),且没有输出。
- 不含有非阻塞赋值语句。
- 函数可以调用其他函数,但是不能调用任务。
Verilog 函数声明格式如下:
function [range-1:0] function_id ;
input_declaration ;
other_declaration ;
procedural_statement ;
endfunction
其中:函数在声明时,会隐式的声明一个宽度为 range、 名字为 function_id 的寄存器变量,函数的返回值通过这个变量进行传递。当该寄存器变量没有指定位宽时,默认位宽为 1。
函数通过指明函数名与输入变量进行调用。函数结束时,返回值被传递到调用处。
函数调用格式如下:
function_id(input1, input2, …);