这篇文章写一下今天早上设计的并行数据到串行数据的转换器,也算是对并行总线和串行总线一个小小的应用,编码过程中也用到了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中得到的仿真图如下:
本文介绍了如何使用Verilog设计一个并行数据到串行数据的转换器,包括寄存器存储并行地址和数据、连接串行单总线、地址和数据的串行输出等功能。设计采用嵌套状态机实现,主状态机包含idle, addr_write, data_write, stop四个状态,并使用task shift8out进行并行到串行的转换。在Modelsim中进行了仿真验证。"
134463630,7406880,真空热重分析仪精密控制技术改造,"['热重分析', '真空技术', '压力控制', '气体气氛', '精密仪器']
2529

被折叠的 条评论
为什么被折叠?



