【牛客网刷题】VL4 移位拼接乘法

👉 写在前面

👉 本系列博客记录牛客网刷题记录

👉 日拱一卒,功不唐捐!


目录

题目描述

题目分析

Verilog 代码

testbench 代码

仿真结果


题目描述

已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)

信号示意图

波形示意图

输入描述

输入信号

d

clk

rst

类型

wire

wire

wire

在testbench中,clk为周期 5ns 的时钟,rst 为低电平复位

输出描述

输出信号

input_grant

out

类型

reg

reg

题目分析

从题目的要求和时序上进行分析,复位信号拉高之后,对接收到的数据进行计算输出,依次输出乘1、乘3、乘7、乘8的数值,并且在第一个乘1的输出值同步拉高输出信号 input_grant,同时需要注意的是,在输入数据过于密集的时候,输入的数据是会被忽略的,也可以看到 input_grant 信号是每 4 个时钟周期拉高一次,因此可以申明一个计数器,用于判定输出值 out 和 有效信号 input_grant。

移位运算

Verilog 中移位操作符号有2种,分别是 “<<” 左移位运算符和 “>>” 右移位运算符。

格式如下:a<<n,a>>n。其中,a代表要移位的操作数,n代表要移几位。两种运算方式都用0来填补移出的空位。

移位操作符对左边的操作数进行向左或向右的位移位操作,第二个操作数,移位位数是无符号数,遵循的操作规律是“左移时先补后移,右移时先移后补”。

在进行移位运算时,应当注意移位前后变量的位数。如果操作数已经定义了位宽,则进行移位后操作数改变,但是其位宽不变。

Verilog 代码

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Author      : Linest-5
// File        : multi_sel.v
// Create      : 2022-10-07 18:59:24
// Revise      : 2022-10-07 19:58:16
// Module Name : multi_sel
// Description : 选择乘积数输出
// Editor      : sublime text3, tab size (4)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
`timescale 1ns/1ns

module multi_sel(
	input      [7:0]    d ,
	input               clk,
	input               rst,   //复位,低有效
	output reg          input_grant,
	output reg [10:0]   out
);
//*************code***********//
reg  [7:0]     d_reg;
reg  [1:0]     cnt;

//循环计数器
always @(posedge clk or negedge rst) begin
	if (!rst) begin
		cnt <= 'd0;
	end
	else begin
		cnt <= cnt + 'd1;
	end
end

//每当合适时间数据来临时将数据寄存
always @(posedge clk or negedge rst) begin
	if (!rst) begin
		d_reg <= 'd0;
	end
	else if (cnt == 'd0) begin
		d_reg <= d;
	end
	else begin
		d_reg <= d_reg;
	end
end

//根据计数值输出相应的数值
always @(posedge clk or negedge rst) begin
	if (!rst) begin
		out <= 'd0;
	end
	else if (cnt == 'd0) begin      
		out <= d;                      //乘1
	end
	else if (cnt == 'd1) begin
		out <= (d_reg << 2) - d_reg;   //乘3
	end
	else if (cnt == 'd2) begin
		out <= (d_reg << 3) - d_reg;   //乘7
	end
	else if (cnt == 'd3) begin
		out <= (d_reg << 3);           //乘8
	end
	else begin
		out <= out;
	end
end

//输出有效数据标志信号
always @(posedge clk or negedge rst) begin
	if (!rst) begin
		input_grant <= 'd0;
	end
	else if (cnt == 'd0) begin
		input_grant <= 'd1;
	end
	else begin
		input_grant <= 'd0;
	end
end

//*************code***********//
endmodule

testbench 代码

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Author      : Linest-5
// File        : tb_multi_sel.v
// Create      : 2022-10-07 19:58:57
// Revise      : 2022-10-07 20:22:50
// Module Name : 
// Description :
// Editor      : sublime text3, tab size (4)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
`timescale 1ns/1ns

module tb_multi_sel();

reg            clk;
reg            rst;     //复位,低有效
reg  [7:0]     d;
wire [10:0]    out;
wire           input_grant;

initial begin
	clk  = 'd1;
	rst <= 'd0;
	#50
	rst <= 'd1;
end

initial begin
	d <= 'd23;
	@(posedge rst);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	d <= 'd7;
	@(posedge clk);
	d <= 'd6;
	@(posedge clk);
	d <= 'd12;
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	d <= 'd4;
	@(posedge clk);
	@(posedge clk);
	d <= 'd9;	
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	@(posedge clk);
	d <= 'd12;
	#100
	$finish;
end

always #5 clk = ~clk;

multi_sel inst_multi_sel (
	.d(d), 
	.clk(clk), 
	.rst(rst), 
	.input_grant(input_grant), 
	.out(out)
);

//verdi     
initial begin
   $fsdbDumpfile("tb_multi_sel.fsdb");
   $fsdbDumpvars(0);
end

endmodule

仿真结果

电路结构图

仿真波形图

在 testbench 中设计了输入几组数据,其中有些数据会输入的比较密集,仿真波形中也能很直观的看出。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linest-5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值