[牛客网刷题][基础篇]1~5

该博客详细介绍了使用Verilog进行数字逻辑电路设计的方法,包括四选一多路器、异步复位的串联T触发器、奇偶校验、移位运算与乘法以及位拆分与运算。每个模块都提供了详细的分析和Verilog代码实现,涵盖了组合逻辑和时序逻辑电路的设计原则,如 sel 的对应关系、复位逻辑、异或运算以及移位乘法等。
摘要由CSDN通过智能技术生成

目录

1.四选一多路器

2.异步复位的串联T触发器

3.奇偶校验

 4.移位运算与乘法

5.位拆分与运算


1.四选一多路器

题目:

 分析:

  • 第一点:先判断题目中的四选一是选择何种通道,查看波形图,可以很明显的看出sel与d1、d2、d3、d0的对应关系
  • 第二点:提供的input中没有clk和rst信号,所以是采用组合电路进行电路设计
  • 第三点:组合电路中可以用always@(*)和assign的类型进行设计,采用assign可以使用sel[0]、sel[1]来进行判断
  • 而采用always@(*)时,则需要将wire的线网类型转变为reg类型即可,这时需要转换输出类型 reg [1:0] mux_out;
`timescale 1ns/1ns

module mux4_1(
    input        [1:0]    d1,d2,d3,d0,
    input        [1:0]    sel,
    output       [1:0]    mux_out
);
//*************code***********//
    reg [1:0] mux_out;
    always@(*)begin
        case(sel)
            2'd0:mux_out <= d3;
            2'd1:mux_out <= d2;
            2'd2:mux_out <= d1;
            2'd3:mux_out <= d0;
        endcase
    end
    
//*************code***********//
endmodule

2.异步复位的串联T触发器

题目:

分析:

  • 第一点:先判断TFT的逻辑表达式,TFF关系为 Q*=Q^T;
  • 第二点:可以明显看出是由两个TFT所组成,所以需要在TFT1和TFT2之间增加一个wire线网类型,将二者连接起来
  • 第三点:需要采用时序逻辑电路进行设计,在时序逻辑电路中采用非阻塞赋值,而在组合逻辑电路中采用阻塞赋值
  • 第四点:低电平复位,在前段设计中,一般采用同步复位较多,异步复位,会产生意料之外的冲突
`timescale 1ns/1ns
module Tff_2 (
input wire data, clk, rst,
output reg q  
);
//*************code***********//
    reg line1;
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)
            line1 <= 1'b0;
        else   
            line1 <= data ^ line1;
    end
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)
            q <= 1'b0;
        else   
            q <= line1 ^ q;
    end

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

3.奇偶校验

题目:

分析:

  • 第一点:先判断题目中如何进行奇偶校验,可以明显看出,当sel = 1时为,奇校验,当sel = 0时,为偶校验。
  • 第二点:判断采用时序逻辑电路还是组合逻辑电路,没有提供clk和rst的信号,所以大概率是组合逻辑电路。
  • 第三点:组合电路中可以用always@(*)和assign的类型进行设计,将check设计为reg类型即可
  • 第四点:如何判断多位数的输入信号,即将X中的所有位逐位进行异或操作,如果有奇数个1,异或的结果将为1,如果有偶数个1,异或的结果将为0。
`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
    reg check;
    always@(*)begin
        case(sel)
            1'b0: //偶校验
                check <= ~^bus;
            1'b1: //奇校验
                check <= ^bus;
        endcase
    end
//将X中的所有位逐位进行异或操作,如果有奇数个1,异或的结果将为1,如果有偶数个1,异或的结果将为0。
//*************code***********//
endmodule

 4.移位运算与乘法

题目:

 分析:

  • 第一点:先判断题目中如何进行移位运算与乘法,可以看出d信号,在每个时钟周期都与不同的数(1/3/7/8)进行相乘,所以可以采用[1:0]的cnt(0/1/2/3)来进行计数,判断在这个时钟周期信号下,与哪一个数相乘。
  • 第二点:可以很明显看到在d的数据相乘,只有在cnt = 0时才发生,即out = d时,所以需要声明reg类型d的存储变量,防止其在其他时间进行一个相乘。
  • 第三点:采用cnt进行状态转移时,最好将不同的变量放到不同的always中进行处理。
  • 第四点:verilog中的数据相乘是通过左移和右移实现的,a<<N即a左移N位,每移动1位就是乘2,多了或者少了再减去即可。还需要注意<<移位操作的优先级,其小于+的优先级,所以要将(din << 1)括起来。
  • 第五点:input_grant在cnt = 0时呈现高电平。
`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 [2:0] cnt;
    reg [7:0] din;
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)
            cnt <= 3'd0;
        else if(cnt == 3'd3)
            cnt <= 3'd0;
        else 
            cnt <= cnt + 1'b1;//自动上升
    end
    
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            out <= 11'd0;
            din <= 7'd0;
            input_grant <= 1'b0;
        end
        else
            case(cnt)
                3'd0:begin
                             out <= d; 
                             din <= d;
                             input_grant <= 1'b1;
                end
                3'd1:begin
                             out <= (din<<1) + din;
                             input_grant <= 1'b0;
                end
                3'd2:begin
                             out <= (din<<3) - din;
                             input_grant <= 1'b0;
                end
                3'd3:begin        
                             out <= (din<<3);
                             input_grant <= 1'b0;
                end
            endcase
    end
//*************code***********//
endmodule

5.位拆分与运算

 分析:

  • 第一点:先判断题目是如何进行位拆分和运算的,给出了逻辑关系,当sel = 0时,记录输入的数据,当sel = 1、2、3时,开始进行加法运算。
  • 第二点:记录validout的状态,sel = 0 时为低电平。
`timescale 1ns/1ns

module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,

output reg [4:0]out,
output reg validout
);
//*************code***********//
    reg [15:0] din;
    always@(posedge clk or negedge rst)begin
        if(rst == 1'b0)begin
            out <= 5'd0;
            din <= 16'd0;
            validout <= 1'b0;
        end
        else
            case(sel)
                2'd0:begin   
                         out <= 5'd0;
                         din <= d;
                         validout <= 1'b0;
                end
                2'd1:begin
                        out <= din[3:0] + din[7:4];
                        validout <= 1'b1;
                end
                2'd2:begin    
                        out <= din[3:0] + din[11:8];
                        validout <= 1'b1;
                end
                2'd3:begin    
                        out <= din[3:0] + din[15:12];
                        validout <= 1'b1;
                end
            endcase
    end

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值