习题一:根据状态转移表实现时序电路
描述
- 某同步时序电路转换表如下,请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。
电路的接口如下图所示
输入描述
- input A
- input clk
- input rst_n
输出描述
- output wire Y
代码实现
`timescale 1ns/1ns module seq_circuit( input A , input clk , input rst_n, output wire Y ); reg q0, q1; always@(posedge clk or negedge rst_n) begin if(~rst_n) begin q1 <= 0; end else begin q1 <= A ^ q0 ^ q1; end end always@(posedge clk or negedge rst_n) begin if(~rst_n) begin q0 <= 0; end else begin q0 <= ~q0; end end assign Y = q0 & q1; endmodule
习题二:根据状态转移图实现时序电路
描述
- 某同步时序电路的状态转换图如下,→上表示“C/Y”,圆圈内为现态,→指向次态。
- 请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。
电路的接口如下图所示,C是单bit数据输入端。
输入描述
- input C
- input clk
- input rst_n
输出描述
- output wire Y
代码实现
`timescale 1ns/1ns module seq_circuit( input C , input clk , input rst_n, output wire Y ); parameter ST0 = 2'b00; parameter ST1 = 2'b01; parameter ST2 = 2'b10; parameter ST3 = 2'b11; reg[1:0] cur_state; reg[1:0] next_state; reg Y_r; always@(posedge clk or negedge rst_n) if(!rst_n) cur_state <= ST0; else cur_state <= next_state; always@(*) case (cur_state) ST0: begin if(C == 1'b0) begin next_state = ST0; end else begin next_state = ST1; end end ST1: begin if(C == 1'b0) begin next_state = ST3; end else begin next_state = ST1; end end ST2: begin if(C == 1'b0) begin next_state = ST0; end else begin next_state = ST2; end end ST3: begin if(C == 1'b0) begin next_state = ST3; end else begin next_state = ST2; end end endcase always@(*) case (cur_state) ST0: begin Y_r = 1'b0; end ST1: begin Y_r = 1'b0; end ST2: begin if(C == 1'b1) Y_r = 1'b1; else Y_r = 1'b0; end ST3: begin Y_r = 1'b1; end endcase assign Y = Y_r; endmodule
习题三:ROM的简单实现
描述
- 实现一个深度为8,位宽为4bit的ROM,数据初始化为0,2,4,6,8,10,12,14。可以通过输入地址addr,输出相应的数据data。
- 接口信号图如下:
- 使用Verilog HDL实现以上功能并编写testbench验证。
输入描述
- clk:系统时钟
- rst_n:异步复位信号,低电平有效
- addr:8bit位宽的无符号数,输入到ROM的地址
输出描述
- data:4bit位宽的无符号数,从ROM中读出的数据
代码实现
`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]; assign data = rom_data[addr]; //保持ROM中的数据不变 always @(posedge clk or negedge rst_n) 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 begin rom_data[0] <= rom_data[0]; rom_data[1] <= rom_data[1]; rom_data[2] <= rom_data[2]; rom_data[3] <= rom_data[3]; rom_data[4] <= rom_data[4]; rom_data[5] <= rom_data[5]; rom_data[6] <= rom_data[6]; rom_data[7] <= rom_data[7]; end endmodule
习题四:边沿检测
描述
- 有一个缓慢变化的1bit信号a,编写一个程序检测a信号的上升沿给出指示信号rise,当a信号出现下降沿时给出指示信号down。
- 注:rise,down应为单脉冲信号,在相应边沿出现时的下一个时钟为高,之后恢复到0,一直到再一次出现相应的边沿。
- 使用Verilog HDL实现以上功能并编写testbench验证。
输入描述
- clk:系统时钟信号
- rst_n:异步复位信号,低电平有效
- a:单比特信号,作为待检测的信号
输出描述
- rise:单比特信号,当输入信号a出现上升沿时为1,其余时刻为0
- down:单比特信号,当输入信号a出现下降沿时为1,其余时刻为0
代码实现
`timescale 1ns/1ns module edge_detect( input clk, input rst_n, input a, output reg rise, output reg down ); reg a_tem; //缓存a的数值 always @(posedge clk or negedge rst_n) if (!rst_n) a_tem <= 1'b0; else a_tem <= a; //检测边沿,给出相应的信号 always @(posedge clk or negedge rst_n) if (!rst_n) begin rise <= 1'b0; down <= 1'b0; end else if (!a_tem && a) //当前一时刻a=0,当前时刻a=1,表示a出现一次上升沿 begin rise <= 1'b1; down <= 1'b0; end else if (a_tem && !a) //当前一时刻a=1,当前时刻a=0,表示a出现一次下降沿 begin down <= 1'b1; rise <= 1'b0; end else begin down <= 1'b0; rise <= 1'b0; end endmodule