资讯详情

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

用序列缓存对比法创建寄存器,随时记录当前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 

或者序列缓存对比法

`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

需要注意的就是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

不能直接判断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

`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

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

vl52也是延后一拍。

`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

`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

标签: s33三极管

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台