Verilog练习1

牛客网 VL1 四选一多路器
多路器一般考虑用三目运算符=A?B:C;超过2路的考虑用基本两路复用器级联
在这里插入图片描述

timescale 1ns/1ns
module mux4_1(
input [1:0]d1,d2,d3,d0,
input [1:0]sel,
output[1:0]mux_out
);
//*************code***********//
    wire [1:0] mux_out1,mux_out2;
    assign mux_out=sel[1]?mux_out1:mux_out2;
    assign mux_out1=sel[0]?d0:d1;
    assign mux_out2=sel[0]?d2:d3;               
//*************code***********//
endmodule`

牛客网 VL2 异步复位的串连T触发器
这题需要注意的是串连的是T触发器而不是D触发器,审题很重要
同时不要忘记阻塞赋值的习惯

`timescale 1ns/1ns
module Tff_2 (
input wire data, clk, rst,
output reg q  
);
//*************code***********//
reg q_mid;
    always@(posedge clk,negedge rst)
        if(!rst)
            q_mid<=0;
        else
            if(data==1)
                q_mid<=~q_mid;
            else
                q_mid<=q_mid;
    always@(posedge clk,negedge rst)
        if(!rst)
            q<=0;
        else
            if(q_mid==1)
                q<=~q;
            else
                q<=q;

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

牛客网 VL3 奇偶校验
本题难在1.审题,sel的功能是当sel为0时输出check取反
2.奇偶校验本质上是一个数按位异或^bus
原理 只有1 xor 0=1因此当1 xor 0 时不变号,忽略0在xor中的作用。当1遇到奇数个1互相xor时结果为1,而1xor 偶数个1时结果为0,而中间遇到多少个0并不影响结果。

`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
wire check_mid;
assign check_mid=^bus;
assign check=sel?check_mid:~check_mid;

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

牛客网 VL4 移位运算与乘法

由于这题状态转换并不复杂,因此仅仅设立单状态mini_state,而不用状态转换模型。
需要注意的是每次时钟脉冲到来时,判断的是前一瞬间的值。

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

always@(posedge clk,negedge rst)
    if(!rst)
        mini_state<=2'b00;
    else
        mini_state<=mini_state+1;//时钟上升沿到来状态+1
always@(posedge clk)
    if(mini_state==2'b00)
        data<=d;//锁存输入数据
always@(posedge clk,negedge rst)
    if(!rst)
        begin
        out<=10'b00_0000_0000;
        input_grant<=0;
        end
    else
        case(mini_state)
            2'b00:
            begin
            out<=d;
            input_grant<=1;
            end
            2'b01:
            begin
            out<=data*3;
            input_grant<=0;
            end   
            2'b10:
            begin
            out<=data*7;
            input_grant<=0;
            end
            2'b11:
            begin
            out<=data*8;
            input_grant<=0;
            end   
        endcase
//*************code***********//
endmodule

牛客网 VL5 位拆分与运算
观察题目波形,本题异步性较强,观察到输出out随输入sel同时改变,因此主要通过assign语句实现组合逻辑,然后用always语句实现输入锁存的时序逻辑。

`timescale 1ns/1ns

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

output [4:0]out,
output validout
);
//*************code***********//
    reg [15:0]d_lock;//锁存输入
    wire [15:0]d1,d2,d3,out1,out2;
    assign d1=d_lock[3:0]+d_lock[7:4];
    assign d2=d_lock[3:0]+d_lock[11:8];
    assign d3=d_lock[3:0]+d_lock[15:12];
    assign validout=sel[0]|sel[1];
    assign out1=sel[0]?d1:0;
    assign out2=sel[0]?d3:d2;
    assign out=sel[1]?out2:out1;
    always@(posedge clk,negedge rst)
        if(~rst)
            d_lock<=d_lock;//复位操作
        else
            begin
                if(~(sel[0]|sel[1]))
                    d_lock<=d;//锁存   
            end
//*************code***********//
endmodule

牛客网 VL9 使用子模块实现三输入大小比较
需要注意的是,由于子模块是时序逻辑电路,因此每次比较都会延时。例如ab比较的结果c1是基于第一个时钟脉冲到来之前一瞬间的a,b值。如果直接将c1与c再进行比较的话,就会产生a,b,c三个信号的同步问题 。因为这样的话,c如果在第二个时钟上升沿到来之前变化时,结果d也会相应变化。也就是说,大小比较不满足同时性,比较的是前一个时钟的a,b和后一个时钟的c,因此为了同步需要为c加一个锁存器进行延时,让锁存器输出的也是前一个时钟脉冲的c值。

`timescale 1ns/1ns
module main_mod(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
	input [7:0]c,
	
	output [7:0]d
);
    wire [7:0]c1,c2;
    son_mod S1(.clk(clk),.rst_n(rst_n),.a(a),.b(b),.c(c1));
    D_delay D1(c,clk,c2);
    son_mod S2(clk,rst_n,c2,c1,d);
endmodule
module son_mod(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
    output [7:0]c
);
    reg [7:0]c_mid;
    always@(posedge clk,negedge rst_n)
        if(!rst_n)
            c_mid<=0;
        else
            begin
            if(a>=b)
                c_mid<=b;
            else
                c_mid<=a;
            end
    assign c=c_mid;
endmodule
module D_delay(
    input [7:0] d,
    input clk,
    output[7:0] q);
    reg [7:0] q_mid;
    always@(posedge clk)
        q_mid<=d;
    assign q=q_mid;
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值