Verilog写题笔记5----------#位拆分与运算#
位拆分与运算
https://www.nowcoder.com/practice/1649582a755a4fabb9763d07e62a9752
有四个输入:
1、时钟信号clk
2、复位信号rst
3、16位数据信号d
4、控制信号sel
两个输出:
1、5位结果输出out
2、输出标志信号valid_out
这个题的意思是这样的:如果sel为0,模块不输出out,并将valid_out拉低表示无输出;同时将d的结果存入模块。如果sel为1,valid_out置高,并且输出d[3:0]+d[7:4]的结果。如果sel为2,valid_out置高,并且输出d[3:0]+d[11:8]的结果。如果sel为3,valid_out置高,并且输出d[3:0]+d[15:11]的结果。注意:只有在sel为0时,数据d才会进入模块。
这道题其实不是很难,因为Verilog可以使用位操作,例如:要输出d的前四位与后四位的和,只需要写:out = d[3:0] +d[7:4]即可。
这道题有clk输入,所以必然是在always模块下的时序电路,同时根据不同的sel有不同的输出,很自然的就想到了case函数。最后程序如下:
`timescale 1ns/1ns module data_cal( input clk, input rst, input [15:0]d, input [1:0]sel, output [4:0]out, //题的输出是wire型,所以要有一个reg型的中间变量才能在always中赋值 output validout //题的输出是wire型,所以要有一个reg型的中间变量才能在always中赋值 ); //*************code***********// reg [15:0] flag; //用来储存输入d的中间变量 reg [4:0] out_reg; //out的reg形式 reg validout_reg; //validout的reg形式 assign out = out_reg; //用assign将两者连起来 assign validout = validout_reg; always@(posedge clk or negedge rst) if(rst == 1'b0) //复位 begin out_reg <= 5'd0; validout_reg <= 1'b0; flag <= 16'd0; end else case(sel) //使用case将不同的sel对应不同的操作 2'd0:begin //0时将validout置0,输出置0,并将d存入中间变量 validout_reg <= 1'b0; out_reg <= 5'd0; flag <= d; end 2'd1:begin //1时将validout置1,输出[3:0]+[7:4] validout_reg <= 1'b1; out_reg <= flag[3:0] + flag[7:4]; end 2'd2:begin //2时将validout置1,输出[3:0]+[11:8] validout_reg <= 1'b1; out_reg <= flag[3:0] +flag[11:8]; end 2'd3:begin //2时将validout置1,输出[3:0]+[15:12] validout_reg <= 1'b1; out_reg <= flag[3:0] +flag[15:12]; end default:begin //case最后加上default是良好的习惯 validout_reg <= 1'b0; out_reg <= 5'd0; end endcase //*************code***********// endmodule
verilog写题笔记 文章被收录于专栏
写Verilog题目的一些笔记备忘