Verilog实现常见电路(一)

计划将常见电路的verilog实现进行总结,如有不对的地方,欢迎大家批评指正,先放目录

一、边沿检测

二、串并转换

三、分频器

一、边沿检测

首先对数据打两拍,然后通过两拍数据之间的逻辑关系来判断出是上升沿还是下降沿

module edge_detect(
    input clk,
    input rst_n,
    input data,

    output pos_edge,
    output neg_edge
);

reg data_d0,data_d1;
always@(posedge clk or negedge rst_n)
    if(~rst_n)begin
        data_d0 <= 'h0;
        data_d1 <= 'h0;
    end
    else begin
        data_d0 <= data;
        data_d1 <= data_d0;
    end

assign pos_edge = data_d0 && ~data_d1;
assign neg_edge = ~data_d0 && data_d1;

endmodule

仿真代码

module tb_edge_detect();

parameter PERIOD = 10;

bit clk;
reg rst_n;
reg data;
wire pos_edge;
wire neg_edge;

always #(PERIOD/2) clk = ~clk;

initial begin
    rst_n=1'b1;
    #20;
    rst_n=1'b1;
    @(posedge clk);
    data=1'b1;
    #40;
    data=1'b0;
    #40;
    data=1'b1;
    #40;

end

edge_detect u_edge_detect(
    .clk      (clk      ),
    .rst_n    (rst_n    ),
    .data     (data     ),
    .pos_edge (pos_edge ),
    .neg_edge (neg_edge )
);

endmodule

仿真波形

二、串并转换

1、串转并

输入1bit位宽的数据将其合并为8bit位宽数据输出,输入输出都通过valid来表明此数据有效、

可以通过两种方式实现,计数器和移位寄存器。

module serial2parallel(
    input wire clk,
    input wire rst_n,
    input wire data_in,
    input wire valid_i,

    output reg [7:0] data_o,
    output wire valid_o
);
reg [2:0] cnt;
always@(posedge clk or negedge rst_n)
    if(~rst_n)begin
        cnt<='h0;
        data_o<='h0;
    end
    else if(valid_i)begin
        if(cnt==3'b111)
            cnt<='h0;
        else begin
//方法一:计数器
            data_o[cnt]<=data_in;   //低位优先
            // data_o[7-cnt]<=data_in;   //高位优先
//方法二:移位寄存器
            //data_o<={data_o[6:0],data_in};  //低位优先
            //data_o<={data_in,data_o[7:1]};  //高位优先
            cnt<=cnt+1'b1;
        end
    end

assign valid_o = (cnt==3'b111)? 1'b1:1'b0;

endmodule

仿真代码

`timescale 1ns/1ps
module tb_serial2parallel();

parameter PERIOD=10;

bit clk;
reg rst_n;
reg data_in;
reg valid_i;
wire [7:0] data_o;
wire valid_o;

always #(PERIOD/2) clk = ~clk;

initial begin
    rst_n = 0;
    #PERIOD;
    rst_n =1;
    #PERIOD;

end

always@(posedge clk or negedge rst_n)
    if(~rst_n)begin
        valid_i <= 0;
        data_in <= 1'b0;         
    end
    else begin
        valid_i = 1;
        data_in <= ($random)%2; 
    end

serial2parallel u_serial2parallel(
    .clk     (clk     ),
    .rst_n   (rst_n   ),
    .data_in (data_in ),
    .valid_i (valid_i ),
    .data_o  (data_o  ),
    .valid_o (valid_o )
);
endmodule

仿真波形

2、并转串

输入8bit位宽的数据将其转换为1bit位宽的数据输出,输入输出都通过valid来表明此数据有效

module parallel2serial(
    input wire clk,
    input wire rst_n,
    input wire [7:0] data_in,
    input wire valid_i,

    output reg data_o,
    output reg valid_o
);
reg [2:0] cnt;
reg [7:0] data;
reg bit_flag;

always@(posedge clk or negedge rst_n)
    if(~rst_n)
        data_o<='h0;
    else if(valid_i)
        data<=data_in;
    else if(bit_flag)
        data_o<=data[cnt];

always@(posedge clk or negedge rst_n)
    if(~rst_n)
        bit_flag<=1'b0;
    else if(valid_i)
        bit_flag<=1'b1;
    else if(cnt==3'b111)
        bit_flag<=1'b0;

always@(posedge clk or negedge rst_n)
    if(~rst_n)
        valid_o<=1'b0;
    else if(bit_flag)
        valid_o<=1'b1;
    else
        valid_o<=1'b0;

always@(posedge clk or negedge rst_n)
    if(~rst_n)
        cnt<='h0;
    else if(bit_flag)
        if(cnt==3'b111)
            cnt<='h0;
        else
            cnt<=cnt+1'b1;

endmodule

仿真代码

`timescale 1ns/1ps
module tb_parallel2serial();

parameter PERIOD=10;

bit clk;
reg rst_n;
reg [7:0] data_in;
reg  valid_i;
wire data_o;
wire valid_o;

always #(PERIOD/2) clk = ~clk;

initial begin
    rst_n = 0;
    #PERIOD;
    rst_n =1;
    #PERIOD;
    valid_i = 0;
    generate_data();
    #200;
    generate_data();

end

task generate_data;
begin
    @(posedge clk);
    valid_i = 1;
    data_in = ($random)%20;
    @(posedge clk);
    valid_i= 0;
end
endtask

parallel2serial u_parallel2serial(
    .clk     (clk     ),
    .rst_n   (rst_n   ),
    .data_in (data_in ),
    .valid_i (valid_i ),
    .data_o  (data_o  ),
    .valid_o (valid_o )
);

endmodule

仿真波形

三、分频器

见之前总结过的文章

https://blog.csdn.net/weixin_40634481/article/details/122893950?spm=1001.2014.3001.5501icon-default.png?t=M0H8https://blog.csdn.net/weixin_40634481/article/details/122893950?spm=1001.2014.3001.5501

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. setup time 和 hold time 不满足情况下应该如何解决? 2. 什么叫做亚稳态,如何解决? 3. Verilog中 => 和 = 有什么区别? 4. 画一个D触发器的原理图(门级),并且用verilog gate level表示出来; 5. 用最少的Mos管画出一个与非门; 6. 写一段finite state machine(主要考察coding style);如果触发器的setup time/hold time不满足,这个数据就不能被这一时钟打入触发器,只有在下一个时钟上升沿到来时,数据才能被打入触发器。 在同步系统中,如果触发器的setup time/hold time不满足,就可能产生亚稳态(Metastability),导致采样错误。此时触发器输出端Q在有效时钟沿之后比较长的一段时间处于不确定的状态,在这段时间里Q端毛刺、振荡、固定的某一电压值,而不是等于数据输入端D的值。这段之间成为决断时间(resolution time)。经过resolution time之后Q端将稳定到0或1上,但是究竟是0还是1,这是随机的,与输入没有必然的关系。 只要系统中有异步元件,亚稳态就是无法避免的,因此设计的电路首先要减少亚稳态导致错误的发生,其次要使系统对产生的错误不敏感。前者需要同步来实现,而后者根据不同的设计应用有不同的处理办法 题目是都用英文写的,我用汉字来表达 1, a为输入端,b为输出端,如果a连续输入为1101则b输出为1,否则为0 例如a:0001100110110100100110 b:0000000000100100000000 请画出state machine 2, 请用RTL描述上题state machine 3,library IEEE;

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值