首页 > 技术文章 > verilog--实现数据的串并转换

shadow-fish 2020-08-05 21:30 原文

并行转串行--用这个测试用例是最简单易懂的,这个测试用例需要使用使能信号端。当然还可以用计数器就稍微麻烦一点。

module parallel(clk, rst_n, en, din, dout);

input clk;
input rst_n;
input en;
input [7:0]din;
output dout;
reg dout;
reg [6:0]dout_1;
always@(posedge clk )begin
  if(!rst_n)begin
    {dout_1,dout} <=8'b0; //通过拼接符,可减少触发器端口数
  end
  else begin
    if(en) begin
      {dout_1,dout} <= din;
    end
    else begin
        {dout_1,dout} <= {1'b0,dout_1};
        end
  end
end
endmodule

tb:

`timescale 1ns/1ps
module parallel_tb;
reg clk;
reg rst_n;
reg en;
reg [7:0]din;
wire dout;

parallel u1(
    .clk(clk),
    .rst_n(rst_n),
    .en(en),
    .din(din),
    .dout(dout)
);

initial begin
    clk=1'b1;
    rst_n=1'b0;
    en=1'b0;
    #8;
    rst_n=1'b1;
    #2;
    en=1'b1;
    #10;
    en=1'b0;
    #70;
    en=1'b1;
    #10;
    en=1'b0;
end
always #5 clk=~clk;
initial begin
    #10;
    din=8'b0110_1100;
    #80;
    din=8'b11110000;
    #150;
    $stop();
end
endmodule

 

 

串行转并行--每四位进行一次输出,并含有标志位,串转并:4bit一输出。可直接修改参数进行8bit一输出都可行。

module chuan_bing (
    clk,rst_n,d_in,d_out,d_one
);
    input clk;
    input rst_n;
    input d_in;
    output [3:0]d_out;//输出4位
    output d_one;//满四位输出标志
    reg [1:0]cnt;
    reg d_one;
    reg d_one_1;
    reg [3:0]d_out;
    reg [3:0]d_out_1;
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            d_out_1 <= 4'bx;
        end
        else begin
            d_out_1[cnt] <= d_in;
        end
    end
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            d_out <= 4'b0;
        end
        else if (d_one_1) begin
            d_out <= d_out_1;
            d_one <= d_one_1;
        end
        else begin
            d_out <= 4'b0;
            d_one <= d_one_1;
        end
    end
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            cnt <= 2'b0;
            d_one_1 <= 1'b0;
        end
        else if(cnt == 2'b11) begin
            cnt <= 2'b0;
            d_one_1 <= 1'b1;
        end
        else begin
            cnt <= cnt + 1'b1;
          d_one_1 <= 1'b0;
        end
    end
endmodule

 tb:

`timescale 1ns/1ps
module chuan_bing_tb;
    
    reg clk;
    reg rst_n;
    reg d_in;
    wire [3:0]d_out;
    wire d_one;
    chuan_bing u1(
    clk,rst_n,d_in,d_out,d_one
);
    initial begin
        clk = 1'b1;
        rst_n = 1'b0;
        #10;
        rst_n = 1'b1;
    end
    always #5 clk = ~clk;
    initial begin
        repeat(16) begin
            #10;
            d_in = {$random}%2;
        end
    end
endmodule

 

推荐阅读