移位运算与乘法

描述

题目描述:           

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

信号示意图:

波形示意图:

输入描述:

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

输出描述:

        输出信号 input_grant    out
        类型  reg 

解题分析:

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

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

代码如下:

`timescale 1ns/1ns
module vl4 (
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//*************code***********//
    reg [1:0] cnt;
    reg [7:0] reg_d;
//*******计数器初始化及赋值*******//    
always@(posedge clk or negedge rst)
    if(rst == 1'b0)
        cnt <= 2'd0;
    else if(cnt == 2'd3)
        cnt <= 2'd0;
    else 
        cnt <= cnt + 1'b1;
//***数据寄存器(reg_d)和输入有效标志(input_grant)初始化及赋值***// 
always@(posedge clk or negedge rst)
    if(rst == 1'b0)begin
        reg_d <= 8'd0;
        input_grant <= 1'b0;
    end
    else if(cnt == 2'd0)begin
        reg_d <= d;
        input_grant <= 1'b1;
    end
    else begin
        reg_d <= reg_d;
        input_grant <= 1'b0;
    end
//****乘法运算****//       
always@(posedge clk or negedge rst)
    if(rst == 1'b0) 
        out <= 11'd0;
    else case (cnt)
        2'd0 : out <= d;
        2'd1 : out <= (reg_d<<2)-reg_d;
        2'd2 : out <= (reg_d<<3)-reg_d;
        2'd3 : out <= (reg_d<<3);
        default : out <= 11'd0;
    endcase
//*************code***********//
endmodule

测试代码:

`timescale 1ns/1ns
module tb_vl4();
reg clk;
reg rst;
reg [7:0] d;

wire input_grant;
wire [10:0] out;
//***时钟,复位,d信号赋值***//
initial 
    begin
        clk = 1'b0;
        rst = 1'b0;
        d   = 8'd0;
        #30
        rst = 1'b1;             
        d   = 8'd8;
        #80
        d   = 8'd9;
        #80
        d   = 8'd10;
    end 
//***生成时钟信号***//
always #10 clk =~clk;
//***模块实例化***//    
vl4 vl4_inst
(
    .d          (d) ,
    .clk        (clk) ,
    .rst        (rst) ,
    .input_grant(input_grant) ,
    .out        (out)
);        
    
endmodule

波形图:

alt

相关推荐

  1. C/C++中的整数乘法运算汇编指令MUL和IMUL

    2024-04-03 06:30:06       35 阅读
  2. pytorch | pytorch常用的乘法运算

    2024-04-03 06:30:06       38 阅读
  3. 矩阵的运算:加减乘除转置#matlab

    2024-04-03 06:30:06       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-03 06:30:06       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-03 06:30:06       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-03 06:30:06       82 阅读
  4. Python语言-面向对象

    2024-04-03 06:30:06       91 阅读

热门阅读

  1. 回溯大学生活

    2024-04-03 06:30:06       33 阅读
  2. FPGA简介

    2024-04-03 06:30:06       37 阅读
  3. 2、趁热打铁,Docker实战

    2024-04-03 06:30:06       41 阅读
  4. 设计模式之桥接模式

    2024-04-03 06:30:06       42 阅读
  5. 全球化浪潮下的技术与安全

    2024-04-03 06:30:06       38 阅读
  6. 有哪些常见的网络安全威胁?

    2024-04-03 06:30:06       41 阅读
  7. Spring Boot项目中如何对Bean进行校验

    2024-04-03 06:30:06       41 阅读
  8. Spring Boot 热部署配置

    2024-04-03 06:30:06       39 阅读
  9. centos安装Rust

    2024-04-03 06:30:06       37 阅读
  10. Android adb 常用命令

    2024-04-03 06:30:06       40 阅读
  11. 深入理解Spring Boot Controller层的作用与搭建过程

    2024-04-03 06:30:06       38 阅读
  12. el-table的复选框勾选整行变色

    2024-04-03 06:30:06       35 阅读