FSM设计之二-----并行数据流转特殊串行数据流
2010-11-28 17:45
656 查看
夏宇闻《Verilog 数字系统设计教程》P216
设计两个可综合电路模块:M1模块能把4位的并行数据转换为符合以下协议的串行数据流,数据流用scl和sda两条线传输,sclk为输入的时钟信号,data[3:0]为输入数据,ack为M1的请求M0发新数据信号。第二个模块M2能把串行数据流内的信息接收到,并转换为相应16条信号线的高电平,即若数据为1,则第一条线路为高电平,数据为n,则第n条数据线为高电平。M0为 测试用的信号发生模块,该模块接收M1发出的ack信号,并产生新的测试数据data[3:0]。
通信协议:scl为不断输出的时钟信号,如果scl为高电平时,sda由高变低时刻,串行数据流开始;如果scl为高电平时,sda由低变高时刻,串行数据流结束。sda信号的串行数据位必须在scl为低电平时变化,若变为高则为1,否则为0。
M1模块的代码如下
M2模块的代码如下
信号测试模块:
就会出现下面的结果:
FSM的设计,用状态变量来记住曾经发生过的事情,这些曾经发生过的事情对于电路下一步时钟操作有非常重要的作用。
在本例程中,无论M1和M2模块的设计都必须用状态变量记住目前所处的状态,才能正确地控制输入和输出。可综合模块的设计必须在电路总体结构明确的情况下,
用状态机写出控制的节拍和步骤后才能进行。
设计两个可综合电路模块:M1模块能把4位的并行数据转换为符合以下协议的串行数据流,数据流用scl和sda两条线传输,sclk为输入的时钟信号,data[3:0]为输入数据,ack为M1的请求M0发新数据信号。第二个模块M2能把串行数据流内的信息接收到,并转换为相应16条信号线的高电平,即若数据为1,则第一条线路为高电平,数据为n,则第n条数据线为高电平。M0为 测试用的信号发生模块,该模块接收M1发出的ack信号,并产生新的测试数据data[3:0]。
通信协议:scl为不断输出的时钟信号,如果scl为高电平时,sda由高变低时刻,串行数据流开始;如果scl为高电平时,sda由低变高时刻,串行数据流结束。sda信号的串行数据位必须在scl为低电平时变化,若变为高则为1,否则为0。
M1模块的代码如下
`timescale 1ns/1ns module ptosda ( input sclk, input rst_n, input [3:0] data, output reg ack, output reg scl, output sda ); reg link_sda; reg sdabuf; reg [3:0] databuf; reg [7:0] state; parameter ready = 8'b0000_0001, start = 8'b0000_0010, bit1 = 8'b0000_0100, bit2 = 8'b0000_1000, bit3 = 8'b0001_0000, bit4 = 8'b0010_0000, bit5 = 8'b0100_0000, stop = 8'b1000_0000, idle = 8'b0000_0000; assign sda = link_sda?sdabuf:1'bz; always @ (posedge sclk,negedge rst_n) begin if(!rst_n) scl <= 1'b1; else scl <= ~scl; end always @ (posedge ack) begin databuf <= data; end always @ (negedge sclk or negedge rst_n) begin if(!rst_n) begin link_sda<=1'b0; state <= ready; sdabuf<=1'b1; ack<=1'b0; end else begin case(state) ready: if(ack) begin link_sda<=1'b1; state <= start; end else begin link_sda<=1'b0; state<=ready; ack<=1'b1; end start: if(scl && ack) begin sdabuf<=1'b0; state<=bit1; end else state<= start; bit1: if(!scl) begin sdabuf<=databuf[3]; state<=bit2; ack<=1'b0; 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<=1'b0; state<=stop; end else state<=bit5; stop: if(scl) begin sdabuf<=1'b1; state<=idle; end else state<=stop; idle: begin link_sda<=1'b0; state<=ready; end default: begin link_sda<=1'b0; sdabuf<=1'b1; state<=ready; end endcase end end endmodule
M2模块的代码如下
`timescale 1ns/1ns module out16hi ( input scl, input sda, output reg [15:0] outhigh, output reg [3:0] pdata, output reg [3:0] pdatabuf, output reg start_flag, output reg end_flag, output reg [5:0] mstate ); //reg [5:0] mstate;/* synthesis preserve*/ //reg [3:0] pdatabuf; //reg start_flag,end_flag; always @ (negedge sda) begin if(scl) start_flag<=1'b1; else if(end_flag) start_flag<=1'b0; end always @ (posedge sda) begin if(scl) begin end_flag<=1'b1; pdatabuf<=pdata; end else end_flag<=1'b0; end parameter ready = 6'b00_0000, bit0 = 6'b00_0001, bit1 = 6'b00_0010, bit2 = 6'b00_0011, bit3 = 6'b00_0100, bit4 = 6'b00_0101; 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) begin if(start_flag) case(mstate) bit0: begin mstate <= bit1; pdata[3] <= sda; $display("I am is sda bit0"); end bit1: begin mstate <= bit2; pdata[2] <= sda; $display("I am is sda bit1"); end bit2: begin mstate <= bit3; pdata[1] <= sda; $display("I am is sda bit2"); end bit3: begin mstate <= bit4; pdata[0] <= sda; $display("I am is sda bit3"); end bit4: begin mstate <= bit0; $display("I am is sda stop"); end default: mstate <= bit0; endcase else mstate <= bit0; end endmodule
信号测试模块:
data )]顶层模块:`timescale 1ns/1ns module top; wire [3:0] data; wire sclk,scl,sda; wire rst_n; wire [15:0] outhigh; wire [3:0] pdata; wire [3:0] pdatabuf; wire start_flag,end_flag; wire [5:0] mstate; sigdata M0 ( .rst_n(rst_n), .sclk(sclk), .data(data), .ask_for_data(ack) ); ptosda M1 ( .rst_n(rst_n), .sclk(sclk), .ack(ack), .scl(scl), .sda(sda), .data(data) ); out16hi M2 ( .scl(scl), .sda(sda), .outhigh(outhigh), .pdata(pdata), .pdatabuf(pdatabuf), .start_flag(start_flag), .end_flag(end_flag), .mstate(mstate) ); endmodule
仿真结果:
在模块M2的状态机中,如果if(start_flag)没有加上else mstate<=bit0;就会发生状态跳转不正常的现象,只有第一次状态转移正确。
always @ (posedge scl)
begin
if(start_flag)
case(mstate)
bit0:
begin
mstate <= bit1;
pdata[3] <= sda;
$display("I am is sda bit0");
end
bit1:
begin
mstate <= bit2;
pdata[2] <= sda;
$display("I am is sda bit1");
end
bit2:
begin
mstate <= bit3;
pdata[1] <= sda;
$display("I am is sda bit2");
end
bit3:
begin
mstate <= bit4;
pdata[0] <= sda;
$display("I am is sda bit3");
end
bit4:
begin
mstate <= bit0;
$display("I am is sda stop");
end
default:
mstate <= bit0;
endcase
end
就会出现下面的结果:
FSM的设计,用状态变量来记住曾经发生过的事情,这些曾经发生过的事情对于电路下一步时钟操作有非常重要的作用。
在本例程中,无论M1和M2模块的设计都必须用状态变量记住目前所处的状态,才能正确地控制输入和输出。可综合模块的设计必须在电路总体结构明确的情况下,
用状态机写出控制的节拍和步骤后才能进行。
相关文章推荐
- 四组6比特的并行数据转换成串行数据
- 应用程序框架设计之二:分层和层间数据传递(上)
- 应用程序框架设计之二:分层和层间数据传递
- 应用程序框架设计之二:分层和层间数据传递(下)
- 《解剖PetShop》之二:PetShop数据访问层数之据库访问设计
- 8通道同步并行数据采集PCI模块的设计
- 【MPI学习6】MPI并行程序设计模式:具有不连续数据发送的MPI程序设计
- redis数据类型设计和实现(之二)链表
- 实时数据平台设计:解决从OLTP到OLAP实时流转缺失 - 大数据
- 计算机并行与串行数据的处理
- 异步串行对列和同步并行对列的特殊
- 用于并行计算的多线程数据结构,第 2 部分: 设计不使用互斥锁的并发数据结构
- 74HC165并行数据转串行数据
- 应用程序框架设计之二:分层和层间数据传递(上)
- 【MPI学习6】MPI并行程序设计模式:具有不连续数据发送的MPI程序设计
- 《解剖PetShop》之二:PetShop数据访问层数之据库访问设计
- 【嵌入式】数据通信接口小结--串行并行
- 应用程序框架设计之二:分层和层间数据传递(下)
- 数据挖掘系列之四(数据仓库之二):数据仓库设计--Kimball方法
- 企慧Q5快速开发平台系列之二:数据查询设计