牛客网Verilog题解(进阶篇—序列检测&计数器&存储器)

VL25 输入序列连续的序列检测
用序列缓存对比法,创建一个寄存器随时记录当前a的值并判断是否符合题意,注意match要慢一拍。

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);
    
    reg [7:0] a_1;
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            match <= 0;
            a_1 <= 0;
        end  
        else if(a_1 == 8'b01110001)
            match <= 1;
        else
            match <= 0;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            a_1 <= 0;
        else
            a_1 <= {a_1[6:0],a};
    end  
endmodule

VL26 含有无关项的序列检测
还是序列缓存对比法

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);

    reg [8:0] a_1;
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            a_1 <= 0;
            match <= 0;
        end 
        else if((a_1[8:6] == 3'b011) & (a_1[2:0] == 3'b110))
            match <= 1;
        else
            match <= 0;
        end
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            a_1 <= 0;
        else
            a_1 <= {a_1[7:0],a};
    end
    
endmodule

VL27 不重叠序列检测
需要注意的就是match和not_match信号比题目要求的提前了一个周期,小离谱
状态转移图如下:
在这里插入图片描述

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	output reg match,
	output reg not_match
	);
    
    reg [3:0] ns,cs;
    
    parameter 
    start = 4'd0,
    s1 = 4'd1,
    s2 = 4'd2,
    s3 = 4'd3,
    s4 = 4'd4,
    s5 = 4'd5,
    s6 = 4'd6,
    s11 = 4'd7,
    s22 = 4'd8,
    s33 = 4'd9,
    s44 = 4'd10,
    s55 = 4'd11,
    s66 = 4'd12;
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) 
            cs <= start;
        else
            cs <= ns;
    end
    
    always@(*) begin
        case(cs)
            start : ns = data ? s11 :s1;
            s1 : ns = data ? s2 : s22;
            s2 : ns = data ? s3 : s33;
            s3 : ns = data ? s4 : s44;
            s4 : ns = data ? s55 : s5;
            s5 : ns = data ? s66 : s6;
            s6 : ns = data ? s11 :s1;
            s11 : ns = s22;
            s22 : ns = s33;
            s33 : ns = s44;
            s44 : ns = s55;
            s55 : ns = s66;
            s66 : ns = data ? s11 : s1;
            default : ns = data ? s11 : s1;
        endcase
    end
    
    //always@(posedge clk or negedge rst_n) begin
    always@(*) begin
        if(!rst_n) begin
            match = 0;
            not_match = 0;
        end
        else if(cs == s6) begin
            match = 1;
            not_match = 0;
        end
        else if(cs == s66) begin
            match = 0;
            not_match = 1;
        end
        else begin
            match = 0;
            not_match = 0;
        end
    end

endmodule

VL28 输入序列不连续的序列检测
不能直接判断data_1 == 3’b0110,这样会让match的输出延迟一个周期。

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	input data_valid,
	output reg match
	);

    reg [3:0] data_1;
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            data_1 <= 3'b0000;
        else if(data_valid)
            data_1 <= {data_1[2:0],data};
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            match <= 1'b0;
        else if((data_1[2:0] == 2'b011) & (data_valid) & !data)
            match <= 1'b1;
        else 
            match <= 1'b0;
    end
endmodule

VL50 简易秒表

`timescale 1ns/1ns

module count_module(
	input clk,
	input rst_n,

    output reg [5:0]second,
    output reg [5:0]minute
); 

    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            minute <= 0;
        else if(second == 6'd60)
            minute <= minute + 1;
        else 
            minute <= minute;
    end
        
	always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            second <= 0;
        else if(second == 6'd60)
            second <= 6'd1;
        else if(minute == 6'd60)
            second <= 0;
        else
            second <=second + 1;
    end      
endmodule

VL51 可置位计数器
在这里插入图片描述

在这里插入图片描述
很喜欢评论区的一句话,“我猜是个软件大佬自学1天verilog速成,写出来的答案(流汗黄豆)”
number要延后一拍,可以用寄存器num强行拖一拍,没必要做,自己测试能过就好。

vl52也是延后一拍。
L53 单端口RAM

`timescale 1ns/1ns

module RAM_1port(
    input clk,
    input rst,
    input enb,
    input [6:0]addr,
    input [3:0]w_data,
    output wire [3:0]r_data
);
//*************code***********//

    reg [3:0] rom_1 [127:0];
    
    genvar i;
    generate 
        for(i = 0;i < 128;i = i + 1) begin
            always@(posedge clk or negedge rst) begin
                if(!rst)
                    rom_1[i] <= 0;
                else
                    rom_1[addr] = enb ? w_data : rom_1[addr];
            end
        end
    endgenerate
    
    assign r_data = (enb) ? 0 : rom_1[addr];
            
//*************code***********//
endmodule

VL54 RAM的简单实现

`timescale 1ns/1ns
module ram_mod(
	input clk,
	input rst_n,
	
	input write_en,
	input [7:0]write_addr,
	input [3:0]write_data,
	
	input read_en,
	input [7:0]read_addr,
	output reg [3:0]read_data
);
    reg [3:0] rom_1 [7:0];
    
    integer i;
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            for(i = 0;i < 8;i = i + 1) begin
                rom_1[i] <= 0;
            end
        end
        else 
            rom_1[write_addr] = write_en ? write_data : rom_1[write_addr];
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            read_data <= 0;
        else
            read_data <= read_en ? rom_1[read_addr] : 0;
    end
     
endmodule
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值