列表

详情


VL4. 移位运算与乘法

描述

题目描述:           

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

信号示意图:

波形示意图:



输入描述

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

输出描述

输出信号 input_grant    out
类型  reg 

原站题解

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`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 [1:0] state ;
    reg [7:0] d_reg ;
    parameter    
    s0=2'd0,
    s1=2'd1,
    s2=2'd2,
    s3=2'd3;
    always@(posedge clk or negedge rst)
        begin
            if(rst==1'b0)
                state    <=    s0;
            else
                begin
                    case(state)
                        s0:    state    <=    s1    ;
                        s1:    state    <=    s2    ;
                        s2:    state    <=    s3    ;
                        s3:    state    <=    s0    ;
                    endcase
                end
        end
    always@(posedge clk or negedge rst)
        begin
            if(rst==1'b0)
                input_grant    <=    1'b0    ;
            else
                begin
                    case(state)
                        s0:    input_grant    <=    1'b1   ;
                        s1:    input_grant    <=    1'b0    ;
                        s2:    input_grant    <=    1'b0    ;
                        s3:    input_grant    <=    1'b0    ;
                    endcase
                end
        end
    
     always@(posedge clk or negedge rst)
        begin
            if(rst==1'b0)
                out    <=    11'd0    ;
            else
                begin
                    case(state)
                        s0:   
                            begin
                                d_reg  <=    d      ;
                                out    <=    d      ;
                            end
                        s1:    out    <=    (d_reg<<2) - d_reg    ;
                        s2:    out    <=    (d_reg<<3) - d_reg    ;
                        s3:    out    <=    (d_reg<<3)  ;
                    endcase
                end
        end
//*************code***********//
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`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 [1:0]cnt;
    reg [7:0]din;

    always@(posedge clk or negedge rst)  
       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
                        out <= (din <<2) - din;
                        input_grant <= 0;
                    end 
                2:
                    begin
                        input_grant <= 0;
                        out <= (din << 3) - din;
                    end
                3:
                    begin
                        input_grant <= 0;
                        out <= (din << 3);
                     end 
            endcase
        end 
    
    
//*************code***********//
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`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 [1:0]cnt;
    reg  [7:0]din;
    
always@(posedge clk or negedge rst)
        if(rst==1'b0)
        cnt <= 2'b0;
    else if(cnt==2'd3)
        cnt <= 2'b0;
    else
        cnt <= cnt + 1'b1;
    
always@(posedge clk or negedge rst)
        if(rst==1'b0)
        input_grant <= 1'b0;
    else if(cnt==2'd0)
        input_grant <= 1'b1;
    else
        input_grant <= 1'b0;   
    
always@(posedge clk or negedge rst)
        if(rst==1'b0)
        din <= 8'b0;
    else if(cnt==2'd0)
        din <= d;
    else
        din <= din;    
    
    
always @(posedge clk or negedge rst)    
    if(rst==1'b0)
        out <= 11'b0;
    else 
        case(cnt)
            2'd0: out <= d;
            2'd1: out <= (din<<2)-din;
            2'd2: out <= (din<<3)-din;
            2'd3: out <= din<<3;         
        endcase
    
        
    

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

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//*************code***********//
    parameter s0=2'b00,s1=2'b01,s2=2'b11,s3=2'b10;
    reg [1:0] sta;
    reg [7:0] input_reg;
    
    always@(posedge clk or negedge rst) begin
        if(!rst) begin
            sta<=s0;
            input_reg<=0;
            input_grant<=0;
            out<=0;
        end
        else begin
            case(sta)
                s0: begin
                    sta<=s1;
                    input_reg<=d;
                    input_grant<=1;
                    out<=d;
                end
                s1: begin
                    sta<=s2;
                    input_grant<=0;
                    out<=input_reg*3;
                end
                s2: begin
                    sta<=s3;
                    input_grant<=0;
                    out<=input_reg*7;
                end
                s3: begin
                    sta<=s0;
                    input_grant<=0;
                    out<=input_reg*8;
                end
            endcase
        end
    end

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

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//*************code***********//
 wire       [8:0]    tmp_out1;
  wire       [9:0]    tmp_out1_1;
  wire       [11:0]   tmp_out1_2;
  reg        [7:0]    buffer_1;
  wire                when_XuCounter_l17;
  reg        [1:0]    grant_count;
  reg                 grant_valid;
  wire                when_XuCounter_l12;

  assign tmp_out1 = (d * 1'b1);
  assign tmp_out1_1 = (buffer_1 * 2'b11);
  assign tmp_out1_2 = (buffer_1 * 4'b1000);
  assign when_XuCounter_l17 = 1'b1;
  assign when_XuCounter_l12 = (grant_count == 2'b11);
  always @(*) begin
    if(when_XuCounter_l12) begin
      grant_valid = 1'b1;
    end else begin
      grant_valid = 1'b0;
    end
  end

  always @(posedge clk or negedge rst) begin
    if(!rst) begin
      input_grant <= 1'b0;
      out <= 11'h0;
      buffer_1 <= 8'h0;
      grant_count <= 2'b00;
    end else begin
      if(when_XuCounter_l17) begin
        grant_count <= (grant_count + 2'b01);
        if(grant_valid) begin
          grant_count <= 2'b00;
        end
      end
      case(grant_count)
        2'b00 : begin
          out <= {2'd0, tmp_out1};
          input_grant <= 1'b1;
          buffer_1 <= d;
        end
        2'b01 : begin
          out <= {1'd0, tmp_out1_1};
          input_grant <= 1'b0;
        end
        2'b10 : begin
          out <= (buffer_1 * 3'b111);
          input_grant <= 1'b0;
        end
        default : begin
          out <= tmp_out1_2[10:0];
          input_grant <= 1'b0;
        end
      endcase
    end
  end
//*************code***********//
endmodule

上一题