当前位置: 首页 > news >正文

【芯片设计- RTL 数字逻辑设计入门 11 -- 移位运算与乘法】


请阅读【嵌入式开发学习必备专栏 】


文章目录

    • 移位运算与乘法
      • Verilog Code
      • verilog 拼接运算符({})
      • Testbench Code
      • VCS 波形仿真
    • 问题小结

移位运算与乘法

已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)
在这里插入图片描述
在这里插入图片描述
可以看到输入D 的波形在为6的地方比较特殊,从波形上可以看到它只持续了一个时钟周期,但是out 在乘1/3/7/8的时候都是使用这个6,而且根本没有用到d上的128,下一个信号直接是129的4次运算。所以不能根据D的实时变化来计算out的实时变化。

所以在第一个input_grant的时候需要对输入信号进行寄存,寄存持续4个时钟周期都去改变它,直到下个有效数据到的时候再去寄存。乘法操作都是针对寄存下来的值进行。

input_grant 在执行乘1运算的时候拉高,这里采用计数器的方式,在复位的时候计数器归0,一旦复位失效拉成高电平之后就开始计数,计数值为0/1/2/3, 一共是2bits的信号, 根据计数值来判断输出,其实这种方式就是一个简化后的有限状态机的方式。

Verilog Code

module multi_sel(
	input		        clk,
	input		        rstn,
	input[7:0]	        d,
	output reg	        input_grant,
	output reg[10:0]    out
);

reg[1:0] count;
always @(posedge clk or negedge rstn) begin
	if (~rstn) begin
		count <= 2'b0;
	end
	else begin
		count <= count + 1'b1;
	end
end


// FSM methodology
reg[7:0]	d_reg;
always@(posedge clk or negedge rstn) begin
    if (~rstn) begin
		out <= 11'b0;
		input_grant <= 1'b0;
		d_reg <= 8'b0;
	end
	else begin
		case(count)
            2'b00:begin
                out <= d;
                d_reg <= d;
                input_grant <= 1'b1;
            end
            2'b01:begin
                out <= d_reg + {d_reg, 1'b0}; // *3
                input_grant <= 1'b0;
            end
            2'b10:begin
                out <= d_reg + {d_reg, 1'b0} + {d_reg, 2'b0}; // *7
                input_grant <= 1'b0;
            end
            2'b11:begin
                out <= {d_reg, 3'b0}; // *8
                input_grant <= 1'b0;
            end
            default: begin
                out <= d;
                input_grant <= 1'b0;
            end
        endcase
	end
end
endmodule

verilog 拼接运算符({})

a = 2'b10;
b = 3'b101;

则:

c = {a, b} = 5'b10101;
d = {2'b00, a} = 4'b0010;
e = {3{a}} = 6'b101010;
f = {{2{a}, b 1'b1} = 8'b10101011;

拼接乘法

a = 4'b1110;

g = {a, 1'b0} = 5'b11100; // *2

Testbench Code


module test;
    reg         clk;
    reg         rstn;
    reg[7:0]    d;
    reg         input_grant;
    reg[10:0]   out;

    multi_sel multi_sel_test(
        .clk(clk),
        .rstn(rstn),
        .d(d),
        .input_grant(input_grant),
        .out(out)
    );

    initial begin
`ifdef DUMP_FSDB
        $display("Dump fsdb wave!");
        $fsdbDumpfile("test.fsdb");
        $fsdbDumpvars;
`endif
	end
	
	initial begin
        clk = 1'b0;
        rstn = 1'b0;
        d = 8'b0;
        #15
        rstn = 1'b1;
    end

    initial begin
        repeat(200) begin
            #10 clk =~clk;
            $display("---run time ---: %d", $time);
            if ($time >= 1000) begin
                $finish;
            end
        end
    end

    initial begin
        d = 8'd143;
        #30 d = 8'd7;
        #50 d = 8'd6;
        #60 d = 8'd128;
        #50 d = 8'd129;
        #50 $finish;
    end
endmodule

VCS 波形仿真

在这里插入图片描述
从波形图可以看到只有当input_grant 信号为高的时候 data 数据才有效,这里的input_grant 就类似于 AXI总线上的 valid 信号,用来表示数据是否有效。

问题小结

问题1
在这里插入图片描述
systemverilog 中输出信号赋值导致的error。

问题2 rstn 信号一直为0
在这里插入图片描述
检查 rstn 是否赋值为1’b1;

相关文章:

  • 表单标记(html)
  • List 差集
  • LRU缓存
  • RabbitMQ——构建高性能消息传递的应用
  • 详解格式化输入函数scanf
  • 虚拟飞控计算机:飞行控制系统验证与优化的利器
  • 微服务OAuth 2.1扩展额外信息到JWT并解析(Spring Security 6)
  • 【数据分享】1929-2023年全球站点的逐日平均能见度(Shp\Excel\免费获取)
  • Python 小白的 Leetcode Daily Challenge 刷题计划 - 20240209(除夕)
  • Leecode之环形链表进阶
  • 设计模式-行为型模式(下)
  • 【SpringBoot】Redis集中管理Session和自定义用户参数解决登录状态及校验问题
  • 工厂方法模式(Factory Method Pattern)
  • Qt 数据库操作V1.0
  • 2.6日学习打卡----初学RabbitMQ(一)
  • Python进阶:标准库
  • Qt未来市场洞察
  • 基于YOLOv8算法的照片角度分类项目实践
  • 单片机学习笔记---蜂鸣器工作原理
  • 发送get请求并且发送请求头(header),java实现
  • 17家A股城商行一季报扫描:青岛银行营收增速领跑,杭州银行净利增速领跑
  • 贵州锦屏县委原书记舒健已任黔东南州政府办主任
  • 澎湃读报丨央媒头版集中刊发社论,庆祝“五一”国际劳动节
  • 亚马逊拟为商品标注“关税成本”,特朗普致电贝索斯讨说法
  • 陕西省通报6起违反八项规定典型问题,省卫健委原主任刘宝琴违规收受礼品礼金
  • 顺利撤离空间站,神十九乘组踏上回家之旅