zl程序教程

您现在的位置是:首页 >  其他

当前栏目

并行数据流转换为一种特殊串行数据流模块的设计:设计两个可综合的电路模块,第一个模块(M1)能把4位的并行数据转换为符合以下协议的串行数据流

转换模块数据协议 设计 两个 一种 第一个
2023-09-14 09:15:31 时间

并行数据流转换为一种特殊串行数据流模块的设计:
设计两个可综合的电路模块,第一个模块(M1)能把4位的并行数据转换为符合以下协议的串行数据流,数据流用scl和sda两条线传输,sclk为输入的时钟信号,data[3:0]为输入数据,ack为M1请求M0发新数据信号。第二个模块(M2)能把串行数据流内的信息接收到,并转换为相应16条信号线的高电平,即若数据为1,则第一条线路为高电平,数据为n,则第N条线路为高电平。M0为测试用信号模块。该模块接收M1发出的ack信号,并产生新的测试数据[3:0].

在这里插入图片描述
在这里插入图片描述
参考,点击

0,vivado操作,直接将这几个文件添加到vivado的design中去,这个软件会自动识别,RTL文件和测试文件。

在这里插入图片描述

1,第一个可综合模块

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/11/19 21:26:05
// Design Name: 
// Module Name: ptosda
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//



module ptosda(sclk,rst,data,ack,scl,sda);
input sclk,rst,data;
wire [3:0]data;

output scl,sda,ack;
reg scl,ack,link_sda,sdabuf;
reg [3:0]databuf;
reg [7:0]state;

out16hi m2(.scl(scl), .sda(sda), .outhigh() );    //调用M2模块

assign  sda = link_sda ? sdabuf : 1'b0;        //link_sda控制sdabuf输出到串行总线上

parameter  ready  =  8'b0000_0000,
           start  =  8'b0000_0001,
           bit1   =  8'b0000_0010,
           bit2   =  8'b0000_0100,
           bit3   =  8'b0000_1000,
           bit4   =  8'b0001_0000,
           bit5   =  8'b0010_0000,
           stop   =  8'b0100_0000,
           IDLE   =  8'b1000_0000;

always @(posedge sclk or negedge rst)         //主钟sclk产生串行输出时钟clk
       begin
              if (!rst)
                scl <= 1;
              else
                scl <= ~scl;
       end

always @(posedge ack)
       databuf <= data;

always @(negedge sclk or negedge rst)
       if (!rst)
           begin
                 link_sda <= 0;
                 state <= ready;
                 sdabuf <= 1;
                 ack <= 0;
           end
        else  
           begin
              case(state)
              ready : if(ack) 
                        begin 
                           link_sda <= 1;
                           state <= start;
                        end
                      else
                        begin
                           link_sda <= 0;
                           state <= ready;
                           ack <= 1;
                        end
               
               start : if(scl && ack)
                         begin 
                            sdabuf <= 0;
                            state <= bit1;
                         end
                       else
                         state <= start;

                bit1  : if(!scl)
                          begin
                             sdabuf <= databuf[3];
                             state <= bit2;
                             ack <= 0;
                          end
                         else
                          state <= bit1;
                            
                bit2  : if(!scl)
                          begin
                             sdabuf <= databuf[2];
                             state <= bit3;
                          end
                         else
                          state <= bit2;
                            
                bit3  : if(!scl)
                          begin
                             sdabuf <= databuf[1];
                             state <= bit4;
                          end
                         else
                          state <= bit3;
                            
                bit4  : if(!scl)
                          begin
                             sdabuf <= databuf[0];
                             state <= bit5;
                          end
                         else
                          state <= bit4;
                            
                bit5  : if(!scl)
                          begin
                             sdabuf <= 0;
                             state <= stop;
                          end
                         else
                          state <= bit5;
                            
                stop  : if(scl)
                          begin
                             sdabuf <= 1;
                             state <= IDLE;
                          end
                         else
                          state <= stop;
                            
                IDLE  :  begin
                             link_sda <= 0;
                             state <= ready;
                          end
                            
               default  : begin
                             link_sda <= 0;
                             sdabuf <= 1;
                            state <= ready;
                          end
             endcase
          end
endmodule


2,第二个可综合模块

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/11/19 21:26:35
// Design Name: 
// Module Name: out16hi
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module out16hi(scl,sda,outhigh);
input scl,sda;
output [15:0]outhigh;

reg [4:0]mstate;
reg [3:0]pdata,pdatabuf;
reg [15:0]outhigh;
reg StartFlag,EndFlag;              //串行数据开始和结束标志

always @(negedge sda)
     begin
       if (scl)
           StartFlag <= 1;
       else if (EndFlag)
           StartFlag <= 0;
     end

always @(posedge sda)
       if (scl)
          begin
            EndFlag <= 1;
				pdatabuf <= pdata;
          end
       else
            EndFlag <= 0;
       
parameter sbit0 = 5'b0_0001,
          sbit1 = 5'b0_0010,
          sbit2 = 5'b0_0100,
          sbit3 = 5'b0_1000,
          sbit4 = 5'b1_0000;

always @(pdatabuf)                              //接受到的数据转化为相应的输出位的高电平
       begin
         case(pdatabuf)
             4'b0001: outhigh = 16'b0000_0000_0000_0001; 
             4'b0010: outhigh = 16'b0000_0000_0000_0010; 
             4'b0011: outhigh = 16'b0000_0000_0000_0100; 
             4'b0100: outhigh = 16'b0000_0000_0000_1000; 
             4'b0101: outhigh = 16'b0000_0000_0001_0000; 
             4'b0110: outhigh = 16'b0000_0000_0010_0000; 
             4'b0111: outhigh = 16'b0000_0000_0100_0000; 
             4'b1000: outhigh = 16'b0000_0000_1000_0000; 
             4'b1001: outhigh = 16'b0000_0001_0000_0000; 
             4'b1010: outhigh = 16'b0000_0010_0000_0000; 
             4'b1011: outhigh = 16'b0000_0100_0000_0000; 
             4'b1100: outhigh = 16'b0000_1000_0000_0000; 
             4'b1101: outhigh = 16'b0001_0000_0000_0000; 
             4'b1110: outhigh = 16'b0010_0000_0000_0000; 
             4'b1111: outhigh = 16'b0100_0000_0000_0000; 
             4'b0000: outhigh = 16'b1000_0000_0000_0000; 
          endcase
         end

always @(posedge scl)
       if (StartFlag)
          case(mstate)
              sbit0 : begin
                        mstate <= sbit1;
                        pdata[3] <= sda;
                      end

              sbit1 : begin
                        mstate <= sbit2;
                        pdata[2] <= sda;
                      end

              sbit2 : begin
                        mstate <= sbit3;
                        pdata[1] <= sda;
                      end

              sbit3 : begin
                        mstate <= sbit4;
                        pdata[0] <= sda;
                      end

              sbit4 : begin
                        mstate <= sbit0;
                      end
 
              default : mstate <= sbit0;

           endcase
      else   mstate <= sbit0;
endmodule

3,netlist门级网表

在这里插入图片描述

4,testbench测试代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/11/19 21:27:12
// Design Name: 
// Module Name: sigdata_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

// `timescale 1ns/1ns
`define halfperiod 50
 
module sigdata_test(rst,sclk,data,ack_for_data,sda,scl,outhigh);
output rst;
output [3:0]data;
output sclk;
input ack_for_data;
reg rst,sclk;
reg [3:0]data;
 
output sda,scl,outhigh;
wire sda;
wire scl;
wire [15:0]outhigh;
 
ptosda m1(.sclk(sclk), .rst(rst), .data(data), .ack(ack_for_data), .scl(scl), .sda(sda) );
out16hi m2(scl,sda,outhigh);
 
initial
      begin
          rst = 1;
        #10 rst = 0;
        #(`halfperiod*2+3) rst = 1;
      end
 
initial
      begin
          sclk = 0;
          data = 0;
          #(`halfperiod*1000) $stop;
      end
 
always #(`halfperiod) sclk = ~sclk;
 
always @(posedge ack_for_data)
       begin
          #(`halfperiod/2 + 3) data = data + 1;
       end
 
endmodule

5,前仿真波形验证

在这里插入图片描述在这里插入图片描述