【牛客Verilog快速入门】基础语法代码和仿真代码演示 VL4 移位运算与乘法

题目:

描述:

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

信号示意图:

在这里插入图片描述

波形示意图:

在这里插入图片描述

输入描述:

输入信号 d, clk, rst
类型 wire
在testbench中,clk为周期5ns的时钟,rst为低电平复位

输出描述:

输出信号 input_grant out
类型 reg

解答:

1、在硬件中进行乘除法运算是比较消耗资源的一种方法,想要在不影响延迟并尽量减少资源消耗,必须从硬件的特点上进行设计。根据寄存器的原理,由于是二进制,所以进位和退位为x2或者/2,同样除7可以使用进位3然后减去本身的做法,这样就将乘除法运算转化为位运算,这是一种比较简单的整数运算处理。

2、 需要给出一个计数器的状态机,注意d输入不是随时有效的,只有在cnt计数为0的那个时钟沿,d输入有效,因此需要设计一个寄存器din,在cnt为0时候锁存d的值 。

根据题意分析,可以得到状态转换:

设输入为d,计数器为cnt

移位运算逻辑:

位运算
1d
3(din<<2)-din
7(din<<3)-din
8(din<<3)

状态机逻辑:

cntoutinput_grant
0直接输出d,并寄存d的值为din1
1(din<<2)-din0
2(din<<3)-din0
3(din<<3)0

设计代码实现:

在命令行输入g multi.v,复制下面代码:

`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);

reg [1:0]cnt;
reg [7:0]din;

always@(posedge clk or negedge rst) begin
	if(!rst) begin
		cnt <= 0;
		out <= 0;
		input_grant <= 0;
		din <= 0;
	end
	else begin
		cnt <= cnt+1;
		case (cnt)
			0: begin
				din <= d;
				input_grant <= 1;
				out <= d;
			end
			1: begin
				input_grant <= 0;
				out <= (din<<2)-din;
			end		
			2: begin
				input_grant <= 0;
				out <= (din<<3)-din;
			end
			3: begin
				input_grant <= 0;
				out <= (din<<3);
			end	
		endcase
	end



end

endmodule

验证平台实现:

在命令行敲入 g multi.sv,然后复制下面代码:


`timescale 1ns/1ps
module tb_top();
  logic  [7:0] D;
  logic        RST;
  logic        input_grant;
  logic  [10:0] OUT;

  logic clk;

initial begin
    RST = 1;
    #5;
    RST = 0;
    clk = 1;
    #20;
    RST = 1;
    forever #50 clk = ~clk;
end

initial begin
    D = 'h1;
    repeat(3) @(posedge clk);
    D = 'h2;
    repeat(10) @(posedge clk);
    D = 'hA;
    repeat(10) @(posedge clk);
    $finish;
end

multi_sel u0_multi_sel (
    .d(D),
    .clk(clk),
    .rst(RST),
    .input_grant(input_grant),
    .out(OUT)
);

initial begin
    $fsdbDumpfile("tb_top.fsdb");
    $fsdbDumpvars(0, tb_top);
end

endmodule



makefile脚本实现:

在命令行输入g Makefile

akefile 
#// Creator: xiaobaijiang
#// time: 2022-04-21
#// wchat: jianfuk
#//-----------------------------------------------------------



run:	
	vcs -R -full64 +v2k -fsdb  -sverilog multi.v multi_tb.sv -l run.log


verdi:
	verdi -sv multi.v multi_tb.sv  -ssf tb_top.fsdb &



clean:
	@rm -rf verdiLog *.log *.fsdb csrc ucli.key simv* *.conf *.rc 



仿真看波形:

在命令行输入make run,如下图:

在这里插入图片描述
然后在命令行输入make verdi
在这里插入图片描述
更多芯片验证自学教程,请访问->传送门

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白蒋博客

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

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

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

打赏作者

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

抵扣说明:

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

余额充值