侧边栏壁纸
    • 累计撰写 302 篇文章
    • 累计收到 527 条评论
    【Verilog编解码】数据的串并转化
    我的学记|刘航宇的博客

    【Verilog编解码】数据的串并转化

    刘航宇
    2022-09-30 / 0 评论 / 595 阅读 / 正在检测是否收录...

    一、串转并转换模块

    1、利用移位寄存器

    串行转并行数据输出:采用位拼接技术(移位寄存器),将串行的数据总数先表示出来,然后发送一位数据加一,后面的接收的这样标志:
    data_o <= {data_o[6:0],data_i };
    这是左移,右移也是可以的,依据项目而定。
    1输入8输出 的 串转并模块的Verilog代码

    
    module serial_parallel(
        input           clk,
        input           rst_n,en,
        input           data_i,   //一位输入
        output   reg [7:0] data_o    //8位并行输出
        );
    
    always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0)
            data_o <= 8'b0;
        else if (en == 1'b1)
            data_o <= {data_o[6:0], data_i};    //低位先赋值
            //data_o <= {data_i,data_o[7:1],};    //高位先赋值
        else
            data_o <= data_o;
    end
    
    endmodule

    测试代码

    `timescale 1ns/100ps
    module serial_parallel_tb;
    
        reg clk,rst_n,en;
        reg data_i;
        wire [7:0] data_o;
    
        serial_parallel n1(.clk(clk),.rst_n(rst_n),.en(en),.data_i(data_i),.data_o(data_o));
        
        initial begin
        clk = 0;
        rst_n = 0;
        en = 0;
        #20 rst_n = 1;
        #20 en = 1;
            data_i = 1;
        #20 data_i = 0;
        #20 data_i = 1;
        #20 data_i = 0;
        #20 data_i = 1;
        #20 data_i = 1;    
        #20 data_i = 0;
        #20 data_i = 0;
    
        end
        initial begin
        forever #10 clk = ~clk;
        end    
    
    endmodule

    2、利用计数器

    利用计数器cnt 时钟计数,开始数据先给高位,每过一个时钟周期,数据便给低一位。这样便可以达到串转并的效果

    1输入8输出 的 串转并模块的Verilog代码

    module serial_parallel(
        input           clk,
        input           rst_n,
        input           data_i,
        output   reg [7:0] data_o
    );
    
    //msb first   most significant bit 表示二进制数据的最高位
    reg     [2:0]   cnt;     //计数器0-7  
    always @(posedge clk or negedge rst_n)begin
        if(rst_n == 1'b0)begin
            data_o <= 8'b0;
            cnt <= 3'd0;
        end
        else begin
            data_o[7 - cnt] <= data_i;    //高位先赋值
        //data_o[cnt] <= data_i;       //低位先赋值
            cnt <= cnt + 1'b1;
        end
    end
    
    
    endmodule

    测试代码

    
    `timescale 1ns/100ps
    module serial_parallel_tb;
    
        reg clk,rst_n;
        reg data_i;
        wire [7:0] data_o;
    
        serial_parallel n1(.clk(clk),.rst_n(rst_n),.data_i(data_i),.data_o(data_o));
        
        initial begin
        clk = 0;
        rst_n = 0;
        #20 rst_n = 1;
            data_i = 1;
        #20 data_i = 1;
        #20 data_i = 1;
        #20 data_i = 0;
        #20 data_i = 1;
        #20 data_i = 1;    
        #20 data_i = 1;
        #20 data_i = 0;
    
        end
        initial begin
        forever #10 clk = ~clk;
        end    
    
    endmodule

    二、并转串转换模块

    并串转换的原理是:
    先将八位数据暂存于一个四位寄存器器中,然后左移输出到一位输出端口,这里通过一个“移位”指令。
    8输入1输出 的 并转串模块的Verilog代码
    使能信号en表示开始执行并转串操作,由于并转串是移位操作,当一次并转串完成后,需要重新载入待转换的并行数据时,使能信号要再起来一次

    module parallel_serial(clk, rst_n, en, data_i, data_o);
        
        input clk, rst_n,en;
        input [7:0] data_i;
        output data_o;
    
        reg [7:0]  data_buf;
    
        always @(posedge clk or negedge rst_n) begin
        if (rst_n == 1'b0) begin
            
            data_buf <= 8'b0;
        end
        else if (en == 1'b1)
            data_buf <= data_i;
        else
            data_buf <= data_buf <<1;     //将寄存器内的值左移,依次读出
            //data_buf <= {data_buf[6:0],1'b0};
    end
    
        assign data_o = data_buf[7];
    
    endmodule

    测试代码

    `timescale 1ns/100ps
    module parallel_serial_tb;
    
        reg clk,rst_n,en;
        reg [7:0]data_i;
        wire data_o;
    
        serial_parallel n1(.clk(clk),.rst_n(rst_n),.en(en),.data_i(data_i),.data_o(data_o));
        
        initial begin
        clk = 0;
        rst_n = 0;
        en = 0;
        #10 rst_n = 1;
        #15 en = 1;
            data_i = 8'b10111010;
        #10 en = 0;
        #195 en = 1;
             data_i = 8'b10110110;
        #10 en = 0;
    
        
        end
        initial begin
        forever #10 clk = ~clk;
        end    
    
    endmodule

    1
    高速电路系统-传输线阻抗匹配
    « 上一篇 2022-10-10
    Verilog实现FIFO的设计
    下一篇 » 2022-08-31

    评论 (0)

    取消