牛客网verilog题解(快速入门—时序逻辑)

VL21 根据状态转移表实现时序电路
d触发器是不可能d触发器的,这辈子不可能d触发器的。电路图又不会看,就是状态机这种东西,才能维持的了代码这样子,用状态机感觉像回家一样,写状态机里的感觉比家里感觉好多了!里面个个都是人才,代码又简洁,我超喜欢状态机的!
状态机三段式:

//第一段,基本就是死格式了,时序逻辑,非阻塞赋值,传递寄存器的状态
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cs <= ?'b00 ;
        end
        else begin
            cs <= ns ;
        end
    end
//第二段,组合逻辑,阻塞赋值,根据当前状态和当前输入,确定下个状态机状态。
always@(*) begin
   case(cs)
      xx : xxx = (xxx) ? xx : xx;
      xx : xxx = (xxx) ? xx : xx;
      xx : xxx = (xxx) ? xx : xx;
   default:xx = xx;
   endcase
end
//第三段,时序逻辑,非阻塞赋值,根据当前状态和当前输入,确定输出信号。
先reg个工具人,if,else赋值后再assign输出
`timescale 1ns/1ns

module seq_circuit(
      input                A   ,
      input                clk ,
      input                rst_n,
 
      output   wire        Y   
);

reg [1:0] cs,ns;

always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cs <= 2'b00;
        ns <= 2'b00;
    end
    else begin
        cs <= ns;
    end
end

always@(*) begin
    case(cs)
        2'b00 : ns = (A == 1'b1) ? 2'b11 : 2'b01;
        2'b01 : ns = (A == 1'b1) ? 2'b00 : 2'b10;
        2'b10 : ns = (A == 1'b1) ? 2'b01 : 2'b11;
        2'b11 : ns = (A == 1'b1) ? 2'b10 : 2'b00;
    endcase
end

assign Y = (cs == 2'b11) ? 1 : 0;                  
endmodule                   

VL22 根据状态转移图实现时序电路

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   
);

reg [1:0] cs,ns;
reg Y_1;

always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cs <= 2'b00;
        ns <= 2'b00;
    end 
    else begin
        cs <= ns;
    end
end

always@(*) begin
    case(cs)
        2'b00 : ns = (C == 1'b0) ? 2'b00 : 2'b01;
        2'b01 : ns = (C == 1'b0) ? 2'b11 : 2'b01;
        2'b10 : ns = (C == 1'b0) ? 2'b00 : 2'b10;
        2'b11 : ns = (C == 1'b0) ? 2'b11 : 2'b10;
    endcase
end

always@(*) begin
    case(cs)
        2'b00 : Y_1 = 1'b0;
        2'b01 : Y_1 = 1'b0;
        2'b10 : Y_1 = (C == 1'b0) ? 1'b0 : 1'b1;
        2'b11 : Y_1 = 1'b1;
    endcase
end

assign Y = Y_1;
    
endmodule

VL23 ROM的简单实现
[width:0] rom_name [depth:0];位宽每个数据具有多少位;深度表示需要多少个数据。
注意本题在时钟的非上升沿,addr变换时data也要跟着变化,所以assign data = rom[addr];要写在组合逻辑部分。

`timescale 1ns/1ns
module rom(
	input clk,
	input rst_n,
	input [7:0]addr,
	
	output [3:0]data
);

    reg [3:0] rom [7:0];
    assign data = rom[addr];
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
           rom[0] <= 4'd0;
           rom[1] <= 4'd2;
           rom[2] <= 4'd4;
           rom[3] <= 4'd6;      
           rom[4] <= 4'd8;
           rom[5] <= 4'd10;
           rom[6] <= 4'd12;
           rom[7] <= 4'd14;
        end else begin
            rom[0] <= rom[0];
            rom[1] <= rom[1];
            rom[2] <= rom[2];
            rom[3] <= rom[3];
            rom[4] <= rom[4];
            rom[5] <= rom[5];
            rom[6] <= rom[6];
            rom[7] <= rom[7];
        end
    end
endmodule

VL24 边沿检测
将a信号延迟一拍得到a_1信号,即可判断rise/down。

`timescale 1ns/1ns
module edge_detect(
	input clk,
	input rst_n,
	input a,
	
	output reg rise,
	output reg down
);
    
	reg a_1;
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            a_1 <= 0;
            rise <= 0;
            down <= 0;
        end else begin
            if(a & !a_1) begin
                rise <= 1;
                down <= 0;
            end else if(!a & a_1) begin
                rise <= 0;
                down <= 1;
            end else begin
                rise <= 0;
                down <= 0;
            end
        end
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) 
            a_1 <= 0;
        else
            a_1 <= a;
    end     
endmodule
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值