硬件语言Verilog HDL牛客刷题day03 时序逻辑部分

Posted _She001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了硬件语言Verilog HDL牛客刷题day03 时序逻辑部分相关的知识,希望对你有一定的参考价值。

1.VL21 根据状态转移表实现时序电路

1.题目:

某同步时序电路转换表如下,请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。

 

 


2.解题思路

        2.1 首先同步时序电路  , 时钟上升沿触发, 复位信号rst 低电平无效.

        2.2 D 触发器 是一个看 A 输入的 触发器。

        2.3  使用状态机。

    


3.解题代码

        

`timescale 1ns/1ns

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

//根据表格 的要求我们知道,这个需要输出 Y   Y与次态的 Q1,Q0 有关
reg q0,q1;
always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
            q1<=0;
        else
            begin
                q1<= A ^ q0 ^ q1;
            end
    end
always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
            q0<= 0;
        else
            begin
                q0 <= ~q0;
            end
    end

assign Y = q0 & q1;

endmodule


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

1.题目:

某同步时序电路的状态转换图如下,→上表示“C/Y”,圆圈内为现态,→指向次态。

请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。


2.解题思路

使用三段式

1)一段式:整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入和输出;
(2)二段式:用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出;
(3)三段式:在两个always模块描述方法基础上,使用三个always模块,一个always模块采用 同步时序 描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。


3.解题感想

 3.1 在硬件电路的时候, 次态和现态,不好表达, 但是总的来说,使用 always 能解决。

 3.2 使用三段式 的时候 , 题目解决简单一些。

 3.3 列出一个 固定值的变量  使用  parameter  定义。


4.解题代码

`timescale 1ns/1ns

module seq_circuit(
   input    wire       clk  ,
   input    wire       rst_n,
   input    wire       C    ,
   output   reg        Y   
);
    reg [1:0] state, next_state;
    parameter  ST0  =  2'd0;
    parameter  ST1  =  2'd1;
    parameter  ST2  =  2'd2;
    parameter  ST3  =  2'd3;
    
    always@(posedge clk or negedge rst_n) begin
        if (~rst_n)
            state <= 2'd0;
        else
            state <= next_state;
    end
    
    always@(*) begin
        case(state)
            ST0: next_state = C ? ST1 : ST0;
            ST1: next_state = C ? ST1 : ST3;
            ST2: next_state = C ? ST2 : ST0;
            ST3: next_state = C ? ST2 : ST3;
            default: next_state = ST0;
        endcase
    end
    
    always@(*) begin
        if(((state == ST2) && C) || (state == ST3))
            Y = 1'b1;
        else
            Y = 1'b0;
    end
    
endmodule



3.VL23 ROM的简单实现

1.题目:

实现一个深度为8,位宽为4bit的ROM,数据初始化为0,2,4,6,8,10,12,14。可以通过输入地址addr,输出相应的数据data。

接口信号图如下:


2.解题思路

        2.1 开辟一个 深度为 8 ,位宽为 4 bit 的数据寄存器。

        2.2 向开辟的寄存器里面 存入数据。

        2.3 调取这个寄存器的数据, 直接访问器地址。


3.解题感想

        3.1 开辟一个 深度为8 位宽为 4 的寄存器的 方法是  前面是 宽度,后面是深度。 

        例如: reg[3:0]  L[7:0];  //深度为8  ,位宽为4 .


4.解题代码

        

`timescale 1ns/1ns
module rom(
	input clk,
	input rst_n,
	input [7:0]addr,
	
	output [3:0]data
);
reg[3:0] ROM_DATA[7:0];
always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				ROM_DATA[0] <=4'd0;
				ROM_DATA[1] <=4'd2;
				ROM_DATA[2] <=4'd4;
				ROM_DATA[3] <=4'd6;
				ROM_DATA[4] <=4'd8;
				ROM_DATA[5] <=4'd10;
				ROM_DATA[6] <=4'd12;
				ROM_DATA[7] <=4'd14;
			end
		else
			ROM_DATA[0] <=4'd0;
			ROM_DATA[1] <=4'd2;
			ROM_DATA[2] <=4'd4;
			ROM_DATA[3] <=4'd6;
			ROM_DATA[4] <=4'd8;
			ROM_DATA[5] <=4'd10;
			ROM_DATA[6] <=4'd12;
			ROM_DATA[7] <=4'd14;
	end
assign data = ROM_DATA[addr];

endmodule



4.VL24 边沿检测

1.题目:

有一个缓慢变化的1bit信号a,编写一个程序检测a信号的上升沿给出指示信号rise,当a信号出现下降沿时给出指示信号down。
注:rise,down应为单脉冲信号,在相应边沿出现时的下一个时钟为高,之后恢复到0,一直到再一次出现相应的边沿。


2.解题思路

        2.1 首先是一个 次态 和 现态的问题 , 

        2.2 两个 always 分别控制  次态的赋值, 和 次态和现态的对比来输出 rise 和 down 的值.


3. 解题感想

        3.1 使用 if else  嵌套 if else  要使模块专一化, 就是每个部分使用  隔断语句区分 (begin end) ( 并行语句) 。


4. 解题代码

`timescale 1ns/1ns
module edge_detect(
	input clk,
	input rst_n,
	input a,
	
	output reg rise,
	output reg down
);
reg a1;
//首先搞定a 
always@(posedge clk or negedge rst_n)//建立一个寄存器保存上一个时态的信号
	begin
		if(~rst_n)
			a1 <= 0;
		else
			a1 <= a;
	end


always@(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				rise <= 0;
				down <= 0;
			end
		else 
			begin
				if(a & ~a1)//上一时态为 低电平, 现态为 高点品
					begin
						rise <=1'b1;
						down <=1'b0;
					end
				else if(~a & a1) //次态为 高点品  , 现态 为 低电平
					begin
						rise <=0;
						down <=1;
					end
				else
					begin
						rise <=0;
						down <=0;
					end
			end
	end



	
endmodule

以上是关于硬件语言Verilog HDL牛客刷题day03 时序逻辑部分的主要内容,如果未能解决你的问题,请参考以下文章

牛客刷题HJ4 字符串分隔

牛客刷题打卡

牛客刷题打卡

牛客刷题打卡

(基础杂记) —— 2021-07-13 —— 牛客刷题错题记录

(基础杂记) —— 2021-07-13 —— 牛客刷题错题记录