FPGA设计思想之串并转换

数据流中,用面积换速度-串行转并行的操作

并行转串行数据输出:采用计数方法,将并行的数据的总数先表示出来,然后发送一位数据减一,后面的接收的这样表示: data_out <= data[cnt];//cnt表示计数器

`timescale  1ns/1ns

module  p2s
    (
      input         clk,
      input         rst_n,
      input         load,
      input [7:0]   pdata,
      output        sclk,
      output        sdat
    );
`define FULL  4'hf 
reg [3:0]   bitcnt;
reg         en;
reg [7:0]   sbuff;
always @(posedge clk or negedge rst_n)
  if(!rst_n)      en  <=  0;
  else if(load) en  <=  1'b1; 
  else if(bitcnt==`FULL)  en  <= 1'b0; 
always @(posedge clk or negedge rst_n)
 if(!rst_n)  bitcnt  <=  0;
  else if(en) bitcnt  <=  bitcnt + 'b1;
  else  bitcnt  <=  0;
assign  sclk  = bitcnt[0];
always @(posedge clk or negedge rst_n)
  if(!rst_n)  sbuff <=  8'b0;
  else if(load) sbuff <=  pdata;
  else if(sclk) sbuff <=  sbuff<<1;
assign  sdat  = sbuff[7];
endmodule


串行转并行数据输出:采用位拼接结束,将串行的数据总数先表示出来,然后发送一位数据加一,后面的接收的这样标志:data <= {data[6:0],data_out };------用过的74HC595

module SerialToParallel(
    input         CLK,    //时钟
    input         RSTn,    //复位
    input         Enable,    //输入有效
    input         DataIn,    //串行输入
    output reg    Ready,    //输出有效
    output[7:0]    Index,    //并行数据索引
    output[7:0] ParallelData    //并行数据输出
    );
    
    reg[7:0]    Data_Temp;    //数据缓存
    reg[3:0]    counter;    //位数计数器
    reg[3:0]    state;        //状态机
    reg[7:0]    Index_Temp;    //索引缓存
    
    assign    Index=Index_Temp;
    assign    ParallelData=Ready?Data_Temp:8'd0;
    
    ////////////////////////////////////////
    //state:
    //4'd0:复位 
    //
    //4'd1:未复位,未使能
    //
    //4'd2:未复位,输入使能
    //
    
    always@(posedge CLK or negedge RSTn)
    if(!RSTn)
        begin
            state<=4'd0;        //复位
            Ready<=0;
            counter<=4'd0;
            Data_Temp<=8'd0;
            Index_Temp<=8'd0;
        end
    else
        begin
            case(state)
                4'd0:
                begin
                    if(!Enable)state<=4'd1;
                    else state<=4'd2;
                    Ready<=0;
                end
                4'd1:
                begin
                    if(!Enable)state<=4'd1;
                    else state<=4'd2;
                    Ready<=0;
                    counter<=4'd0;
                    Data_Temp<=8'd0;
                end
                4'd2:
                begin
                    if(!Enable)state<=4'd1;
                    else state<=4'd2;
                    case(counter)
                    4'd0:begin Data_Temp[0]<=DataIn;counter<=counter + 1'b1;Ready<=0;end
                    4'd1:begin Data_Temp[1]<=DataIn;counter<=counter + 1'b1;Ready<=0;end
                    4'd2:begin Data_Temp[2]<=DataIn;counter<=counter + 1'b1;Ready<=0;end
                    4'd3:begin Data_Temp[3]<=DataIn;counter<=counter + 1'b1;Ready<=0;end
                    4'd4:begin Data_Temp[4]<=DataIn;counter<=counter + 1'b1;Ready<=0;end
                    4'd5:begin Data_Temp[5]<=DataIn;counter<=counter + 1'b1;Ready<=0;end
                    4'd6:begin Data_Temp[6]<=DataIn;counter<=counter + 1'b1;Ready<=0;end
                    4'd7:begin Data_Temp[7]<=DataIn;counter<=4'd0;Index_Temp<=Index_Temp + 1'b1;Ready<=1'b1;end
                    endcase
                end
            endcase
        end

endmodule
原文地址:https://www.cnblogs.com/Dinging006/p/9486530.html