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

本文介绍了如何使用Verilog设计一个并行数据到串行数据的转换器,包括寄存器存储并行地址和数据、连接串行单总线、地址和数据的串行输出等功能。设计采用嵌套状态机实现,主状态机包含idle, addr_write, data_write, stop四个状态,并使用task shift8out进行并行到串行的转换。在Modelsim中进行了仿真验证。" 134463630,7406880,真空热重分析仪精密控制技术改造,"['热重分析', '真空技术', '压力控制', '气体气氛', '精密仪器']

这篇文章写一下今天早上设计的并行数据到串行数据的转换器,也算是对并行总线和串行总线一个小小的应用,编码过程中也用到了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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值