并行数据转换为串行数据的转换器

这篇文章写一下今天早上设计的并行数据到串行数据的转换器,也算是对并行总线和串行总线一个小小的应用,编码过程中也用到了task。

该转换器主要实现的功能是:

1、把并行地址存入寄存器

2、把并行数据存入寄存器

3、连接串行单总线

4、地址的串行输出

5、数据的串行输出

6、挂起串行单总线

7、给信号源应答

8、让信号源给出下一个操作对象

9、结束写操作

该设计利用嵌套的状态机实现,主状态机分为四个状态:idle,addr_write,data_write,stop,主状态机中会涉及到任务shift8out的调用,该任务主要实现并行数据到串行数据的转换,也是由一个状态机实现。下面给出整个设计的代码:

设计代码:

///并串转换器//
module ps_convertor(clk,rst,data,addr,sda,ack);
parameter idle=4'b0001,addr_write=4'b0010,data_write=4'b0100,stop=4'b1000;//独热编码
parameter sh8_start=9'b00000_0001;
parameter bit6     =9'b00000_0010;
parameter bit5     =9'b00000_0100;
parameter bit4     =9'b00000_1000;
parameter bit3     =9'b00001_0000;
parameter bit2     =9'b00010_0000;
parameter bit1     =9'b00100_0000;
parameter bit0     =9'b01000_0000;
parameter sh8_stop =9'b10000_0000;

          
input clk,rst;
input [7:0]addr,data;
inout sda;//串行总线
output ack;//应答信号将输入测试模块

reg ack;

reg link_write;//写开关
reg [7:0] sh8out_buf;//并行总线缓冲器

reg [3:0] mstate;//主状态机的状态寄存器
reg [8:0] sh8_state;//并串转换状态机状态寄存器

reg FF;//标志寄存器,用来表示任务是否完成

assign sda=(link_write)?sh8out_buf[7]:1'hz;//串行总线数据传输

always@(posedge clk)
begin
 if(!rst)//同步复位
 begin
  mstate<=idle;
  link_write<=0;
  FF<=0;
  sh8out_buf<=0;
  //sh8_state<=sh8_start;
  ack<=0;
 end
 else 
 begin
 case (mstate)
  idle: begin
         mstate<=addr_write;
		 link_write<=0;
		 FF<=0;
		 sh8out_buf<=addr;
		 sh8_state<=sh8_start;
		 ack<=0;
        end
  addr_write: 
        begin
		 if(FF==0)
		  begin
		   shift8out;
		  end
		 else 
		  begin
		   FF<=0;
		   mstate<=data_write;
		   sh8out_buf<=data;
		   sh8_state<=sh8_start;
		  end
		end
  data_write:
        begin
		 if(FF==0)
		  begin
		   shift8out;
		  end
		 else 
		  begin
		   FF<=0;
		   mstate<=stop;
		   ack<=1;
		  end
		end
  stop: begin
         ack<=0;
		 mstate<=idle;
        end
  //default: mstate<=idle;       
 endcase
 end
end
//并串转换模块
task shift8out;
 begin
  case(sh8_state)
   sh8_start: begin
               link_write<=1;
			   sh8_state<=bit6;
              end
   bit6:      begin
               //link_write<=1;
               sh8_state<=bit5;
			   sh8out_buf<=sh8out_buf<<1;
              end
   bit5:      begin
               sh8_state<=bit4;
			   sh8out_buf<=sh8out_buf<<1;
              end
   bit4:      begin
               sh8_state<=bit3;
			   sh8out_buf<=sh8out_buf<<1;
              end
   bit3:      begin
               sh8_state<=bit2;
			   sh8out_buf<=sh8out_buf<<1;
              end
   bit2:      begin
               sh8_state<=bit1;
			   sh8out_buf<=sh8out_buf<<1;
              end
   bit1:      begin
               sh8_state<=bit0;
			   sh8out_buf<=sh8out_buf<<1;
              end
   bit0:      begin
               sh8_state<=sh8_stop;
			   sh8out_buf<=sh8out_buf<<1;
              end
   sh8_stop: begin 
              FF<=1;
			  sh8_state<=sh8_start;
			  link_write<=0;
			 end
			  
  endcase
 end
endtask

endmodule

测试模块:

`timescale 1ns/1ns
`define half_cycle 10
module signal;
reg clk,rst;
reg [7:0]data,addr;
wire sda,ack;
always #(`half_cycle) clk=~clk;
initial 
begin
  rst=1;
  clk=0;
  data=8'b1010_1010;
  addr=0;
  #100 rst=0;
  #100 rst=1;
  #(200* `half_cycle)$stop;
end

always @(posedge ack)
begin
 data=data+1;
 addr=addr+1;
end
 ps_convertor m(clk,rst,data,addr,sda,ack);
endmodule


最终在modelsim中得到的仿真图如下:

并行数据转换为串行数据的转换器_第1张图片


 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(IC模块设计)