题解 | 基础版05#位拆分与运算#
位拆分与运算
http://www.nowcoder.com/practice/1649582a755a4fabb9763d07e62a9752
作者:FPGA探索者
链接:https://www.nowcoder.com/discuss/936631?source_id=profile_create_nctrack&channel=-1
来源:牛客网
链接:https://www.nowcoder.com/discuss/936631?source_id=profile_create_nctrack&channel=-1
来源:牛客网
1. 题目
输入16位数据d[15:0],按照sel选择输出,并输出valid_out信号(在不输出时候拉低)
sel = 0:不输出且只有此时的输入有效
sel = 1:输出d[3:0]+d[7:4]
sel = 2:输出d[3:0]+d[11:8]
sel = 3:输出d[3:0]+d[15:12]
2. 解析
本题目的sel选择输出比较简单,可以用if...else if...else来完成,也可以用第1题提到的case语句实现。
问题的关键在于还是要像第4题一样做寄存。从波形上没有特别明显看出,但是要注意条件:
只有sel=0时的输入有效!所以在sel=0时用d_reg寄存,而sel不等于0时,相加操作用的是寄存数据d_reg拆分相加,而不是用当前的输入d。
这时候我们再仔细观察下波形,发现确实需要寄存。
3. 代码
`timescale 1ns/1ns module data_cal( input clk, input rst, input [15:0]d, input [1:0]sel, output [4:0]out, // wire output validout // wire ); //*************code***********// reg [15:0] d_reg; wire [3:0] d0; wire [3:0] d1; wire [3:0] d2; wire [3:0] d3; assign d0 = d_reg[3:0]; assign d1 = d_reg[7:4]; assign d2 = d_reg[11:8]; assign d3 = d_reg[15:12]; reg [4:0] out_reg; reg validout_reg; always @ (posedge clk&nbs***bsp;negedge rst) begin if( ~rst ) begin out_reg <= 5'b0; validout_reg <= 1'b0; d_reg <= 16'b0; end else begin case( sel ) 2'b00 : begin d_reg <= d; out_reg <= 5'b0; validout_reg <= 1'b0; end 2'b01 : begin d_reg <= d_reg; out_reg <= d_reg[3:0] + d_reg[7:4];// d0 + d1; validout_reg <= 1'b1; end 2'b10 : begin d_reg <= d_reg; out_reg <= d0 + d2; validout_reg <= 1'b1; end 2'b11 : begin d_reg <= d_reg; out_reg <= d0 + d3; validout_reg <= 1'b1; end default : begin out_reg <= 5'b0; validout_reg <= 1'b0; end endcase end end assign out = out_reg; assign validout = validout_reg; //*************code***********// endmodule