题解 | #使用函数实现数据大小端转换#
使用函数实现数据大小端转换
https://www.nowcoder.com/practice/74c0c19ad0c444959c436a049647a93c
使用函数实现数据大小端转换
function (函数)和 task (任务)
都是为了模块化、结构化设计,主要还是将重复性的功能封装起来方便调用。
function
function <返回值类型或范围>(函数名); >>>可以对返回值类型和范围不进行定义,默认值为reg型并且位宽为1
<端口说明语句> >>>声明输入端口
<变量类型说明语句>
begin
<语句> >>>begin end中只能用reg型语句
end
endfunction
function(其功能同之前的module模块类似)
通常是用来描述组合逻辑,是阻塞赋值“="
不能包含任何延迟,函数仿真时间为0
只含有input参数并由函数名返回一个结果(函数名就是返回值)
可以调用其他的函数(function),不可调用task
task <任务名>
<端口及数据类型的声明语句>
<语句1>
<语句2>
...
<语句n>
endtask
task
通常用于调试,对硬件行为级描述,不可综合。
可以包含时序控制(#延迟、wait)
可以有input、output、inout参数
可以调用其他任务或函数,优先级较高
回顾题目
让实现4bit大小位转换的功能。例如4’1101经过变换后变为4‘b1011.
本题的testbench有问题,没有考虑clk和rst_n。所以这里则根据题意写了一份答案。
首先是module部分。因为多次采用大小位转换功能,所以直接将这部分定义为一个function,可以考虑用之前的for循环进行编写。可以缩短一部分。
随后是对function的调用,考虑为时钟上升沿触发,并且异步复位。
结合以上两部分对应的module代码如下:
function [3:0] swap; input [3:0] swap_num; integer i; begin for(i = 0;i < 4;i = i + 1) begin swap[i] = swap_num[3-i]; end end endfunction reg [3:0] c_tmp,d_tmp; always @(posedge clk or negedge rst_n) if(!rst_n) begin c_tmp <= 4'b0; d_tmp <= 4'b0; end else begin c_tmp <= swap(a); d_tmp <= swap(b); endy运用仿真工具编写的testbech文件如下:
`timescale 1ns/1ns module tb_function(); reg [3:0] a,b; reg clk; reg rst_n; wire [3:0] c,d; always #5 clk = !clk; initial begin clk = 0; rst_n = 0; a = 4'b0000; b = 4'b0000; #5 clk = !clk; #10 rst_n = 1; a = 4'b0001;b = 4'b0101; #30 rst_n = 1; a = 4'b1101;b = 4'b1011; #100 $finish; end function_mod dut( .a (a), .b (b), .clk (clk), .rst_n (rst_n), .c (c), .d (d) ); endmodule仿真的波形图如下