描述
题目描述:
已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)
信号示意图:
波形示意图:
输入描述:
输入信号 d, clk, rst
类型 logic
在testbench中,clk为周期5ns的时钟,rst为低电平复位
输出描述:
输出信号 input_grant out
类型 logic
解答:
问题分析:
8位数,乘以1,3,7,8;是对每一个输入的8位数都要进行的,所以是一个死循环,对输入的数据分别乘以1,3,7,8然后输出;下一个进来继续。
因此,状态机是最好解决这个问题的;在每一个状态乘以1,3,7,8然后输出,然后回到初始状态。
对于使能信号,他只在乘以1的时候进行输出为1,所以只在状态机第一态将他拉高即可。
然后再看波形示意图,143到7这块,说明他已经有新的数据输入了,但是他还是之前的数据继续计算,直到乘以8结束。说明需要有一个寄存器存储之前的数据,使得它不随着输入数据的更新而更新。
最后,因为移位运算比乘法运算效率更快,所以可以采用移位运算替代乘法运算。
故,代码如下:
`timescale 1ns/1ns
module multi_sel(
input logic [7:0]d ,
input logic clk,
input logic rst,
output logic input_grant,
output logic [10:0]out
);
//*************code***********//
logic [1:0] state;
logic [7:0] d1;
always @(posedge clk or negedge rst) begin
if(!rst) begin
state<='b0;
out <= 'd0;
input_grant <= 'b0;
d1 <= 'd0;
end else begin
case(state)
'b0: begin
out <= d;
d1 <= d;
input_grant <= 'b1;
state <= state+ 'b1;
end
'b1:begin
out <= (d1 << 2) - d1;
state <= state+ 'b1;
input_grant <= 'b0;
end
'd2:begin
out <= (d1 << 3) - d1;
state <= state +'b1;
end
'd3:begin
out <= d1 << 3;
state <= state + 'b1;
end
default:begin
out <= 'd0;
state <= 'b0;
end
endcase
end
end
//*************code***********//
endmodule