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