FPGA实现双向IO口与时钟芯片的例子

更新时间:2023-07-24 23:55:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

黑金开发板建模篇的实验十三。这个例子包含了IO口的使用、状态机以及完成状态标志的巧妙用法,可以多参考一下其写法。我认为这个例程包含了建模篇大部分的精华和常用方法。 下面将这个例子的全部内容拷贝下来,以备不时之需。也可以提供给需要的网友来参考。

各.v文件的组成架构如下图所示。

module exp13_demo

(

CLK, RSTn,

RST,

SCLK,

SIO,

LED

);

input CLK;

input RSTn;

output RST;

output SCLK;

inout SIO;

output [3:0]LED;

reg [3:0]i;

reg [7:0]isStart;

reg [7:0]rData;

reg [3:0]rLED;

always @ ( posedge CLK or negedge RSTn )

if( !RSTn )

begin

i <= 4'd0;

isStart <= 8'd0;

rData <= 8'd0;

rLED <= 4'd0;

end

else

case( i )

0:

if( Done_Sig ) begin isStart <= 8'd0; i <= i + 1'b1; end

else begin isStart <= 8'b1000_0000; rData <= 8'h00; end

1:

if( Done_Sig ) begin isStart <= 8'd0; i <= i + 1'b1; end

else begin isStart <= 8'b0100_0000; rData <= { 4'd1, 4'd2 }; end

2:

if( Done_Sig ) begin isStart <= 8'd0; i <= i + 1'b1; end

else begin isStart <= 8'b0010_0000; rData <= { 4'd2, 4'd2 }; end

3:

if( Done_Sig ) begin isStart <= 8'd0; i <= i + 1'b1; end

else begin isStart <= 8'b0001_0000; rData <= { 4'd2, 4'd2 }; end

4:

if( Done_Sig ) begin rLED <= Time_Read_Data[3:0]; isStart <= 8'd0; i <= 4'd4; end

else begin isStart <= 8'b0000_0010; end

endcase

wire Done_Sig;

wire [7:0]Time_Read_Data;

ds1302_module U1

(

.CLK( CLK ),

.RSTn( RSTn ),

.Start_Sig( isStart ),

.Done_Sig( Done_Sig ),

.Time_Write_Data( rData ),

.Time_Read_Data( Time_Read_Data ),

.RST( RST ),

.SCLK( SCLK ),

.SIO( SIO )

);

assign LED = rLED;

Endmodule

module ds1302_module

(

CLK, RSTn,

Start_Sig,

Done_Sig,

Time_Write_Data,

Time_Read_Data,

RST,

SCLK,

SIO

);

input CLK;

input RSTn;

input [7:0]Start_Sig;

output Done_Sig;

input [7:0]Time_Write_Data;

output [7:0]Time_Read_Data;

output RST;

output SCLK;

inout SIO;

wire [7:0]Words_Addr;

wire [7:0]Write_Data;

wire [1:0]Access_Start_Sig;

cmd_control_module U1

(

.CLK( CLK ),

.RSTn( RSTn ),

.Start_Sig( Start_Sig ), // input - from top

.Done_Sig( Done_Sig ), // output - to top

.Time_Write_Data( Time_Write_Data ), // input - from top .Time_Read_Data( Time_Read_Data ), // output - to top .Access_Done_Sig( Access_Done_Sig ), // input - from U2 .Access_Start_Sig( Access_Start_Sig ), // output - to U2 .Read_Data( Read_Data ), // input - from U2 .Words_Addr( Words_Addr ), // output - to U2

.Write_Data( Write_Data ) // output - to U2

);

wire [7:0]Read_Data;

wire Access_Done_Sig;

function_module U2

(

.CLK( CLK ),

.RSTn( RSTn ),

.Start_Sig( Access_Start_Sig ), // input - from U1 .Words_Addr( Words_Addr ), // input - from U1

.Write_Data( Write_Data ), // input - from U1

.Read_Data( Read_Data ), // output - to U1

.Done_Sig( Access_Done_Sig ), // output - to U1

.RST( RST ), // output - to top

.SCLK( SCLK ), // output - to top

.SIO( SIO ) // output - to top

);

Endmodule

module cmd_control_module

(

CLK, RSTn,

Start_Sig,

Done_Sig,

Time_Write_Data,

Time_Read_Data,

Access_Done_Sig,

Access_Start_Sig,

Read_Data,

Words_Addr,

Write_Data

);

input CLK;

input RSTn;

input [7:0]Start_Sig;

output Done_Sig;

input [7:0]Time_Write_Data;

output [7:0]Time_Read_Data;

input Access_Done_Sig;

output [1:0]Access_Start_Sig;

input [7:0]Read_Data;

output [7:0]Words_Addr;

output [7:0]Write_Data;

reg [7:0]rAddr;

reg [7:0]rData;

always @ ( posedge CLK or negedge RSTn )

if( !RSTn )

begin

rAddr <= 8'd0;

rData <= 8'd0;

end

else

case( Start_Sig[7:0] )

8'b1000_0000 : // Write unprotect begin rAddr <= { 2'b10, 5'd7, 1'b0 }; rData <= 8'h00; end

8'b0100_0000 : // Write hour

begin rAddr <= { 2'b10, 5'd2, 1'b0 }; rData <= Time_Write_Data; end

8'b0010_0000 : // Write minit begin rAddr <= { 2'b10, 5'd1, 1'b0 }; rData <= Time_Write_Data; end

8'b0001_0000 : // Write second

begin rAddr <= { 2'b10, 5'd0, 1'b0 }; rData <= Time_Write_Data; end

8'b0000_1000 : // Write protect begin rAddr <= { 2'b10, 5'd7, 1'b0 }; rData <= 8'b1000_0000; end

8'b0000_0100 : // Read hour begin rAddr <= { 2'b10, 5'd2, 1'b1 }; end

8'b0000_0010 : // Read minit begin rAddr <= { 2'b10, 5'd1, 1'b1 }; end

8'b0000_0001 : // Read second begin rAddr <= { 2'b10, 5'd0, 1'b1 }; end

endcase

reg [1:0]i;

reg [7:0]rRead;

reg [1:0]isStart;

reg isDone;

always @ ( posedge CLK or negedge RSTn )

if( !RSTn )

begin

i <= 2'd0;

rRead <= 8'd0;

isStart <= 2'b00;

isDone <= 1'b0;

end

else if( Start_Sig[7:3] ) // Write action

case( i )

0 :

if( Access_Done_Sig ) begin isStart <= 2'b00; i <= i + 1'b1; end

else begin isStart <= 2'b10; end

1 :

begin isDone <= 1'b1; i <= i + 1'b1; end

2 :

begin isDone <= 1'b0; i <= 2'd0; end

endcase

else if( Start_Sig[2:0] ) // Read action

case( i )

0 :

if( Access_Done_Sig ) begin rRead <= Read_Data; isStart <= 2'b00; i <= i + 1'b1; end

else begin isStart <= 2'b01; end

1 :

begin isDone <= 1'b1; i <= i + 1'b1; end

2 :

begin isDone <= 1'b0; i <= 2'd0; end

endcase

assign Done_Sig = isDone;

assign Time_Read_Data = rRead;

assign Access_Start_Sig = isStart;

assign Words_Addr = rAddr;

assign Write_Data = rData;

Endmodule

module function_module

(

CLK, RSTn,

Start_Sig,

Words_Addr,

Write_Data,

Read_Data,

Done_Sig,

RST,

SCLK,

SIO

);

input CLK;

input RSTn;

input [1:0]Start_Sig;

input [7:0]Words_Addr;

input [7:0]Write_Data;

output [7:0]Read_Data;

output Done_Sig;

output RST;

output SCLK;

inout SIO;

parameter T0P5US = 5'd24;//50M*(0.5e-6)-1=24

reg [4:0]Count1;

always @ ( posedge CLK or negedge RSTn )

if( !RSTn )

Count1 <= 5'd0;

else if( Count1 == T0P5US )

Count1 <= 5'd0;

else if( Start_Sig[0] == 1'b1 || Start_Sig[1] == 1'b1 ) Count1 <= Count1 + 1'b1;

else

Count1 <= 5'd0;

reg [5:0]i;

reg [7:0]rData;

reg rSCLK;

reg rRST;

reg rSIO;

reg isOut;

reg isDone;

always @ ( posedge CLK or negedge RSTn )

if( !RSTn )

begin

i <= 6'd0;

rData <= 8'd0;

rSCLK <= 1'b0;

rRST <= 1'b0;

rSIO <= 1'b0;

isOut <= 1'b0;

isDone <= 1'b0;

end

else if( Start_Sig[1] )

case( i )

0 :

begin rSCLK <= 1'b0; rData <= Words_Addr; rRST <= 1'b1; isOut <= 1'b1; i <= i + 1'b1; end

1, 3, 5, 7, 9, 11, 13, 15 : if( Count1 == T0P5US ) i <= i + 1'b1;

else begin rSIO <= rData[ (i >>

1) ]; rSCLK <= 1'b0; end

2, 4, 6, 8, 10, 12, 14, 16 : if( Count1 == T0P5US ) i <= i + 1'b1;

else begin rSCLK <= 1'b1; end

17 :

begin rData <= Write_Data; i <= i + 1'b1; end

18, 20, 22, 24, 26, 28, 30, 32 : if( Count1 == T0P5US ) i <= i + 1'b1;

else begin rSIO <= rData[ (i >>

1) - 9 ]; rSCLK <= 1'b0; end

19, 21, 23, 25, 27, 29, 31, 33 : if( Count1 == T0P5US ) i <= i + 1'b1;

else begin rSCLK <= 1'b1; end

34 :

begin rRST <= 1'b0; i <= i + 1'b1; end

35 :

begin isDone <= 1'b1; i <= i + 1'b1; end

36 :

begin isDone <= 1'b0; i <= 6'd0; end

endcase

else if( Start_Sig[0] )

case( i )

0 :

begin rSCLK <= 1'b0; rData <= Words_Addr; rRST <= 1'b1; isOut <= 1'b1; i <= i + 1'b1; end

1, 3, 5, 7, 9, 11, 13, 15 : if( Count1 == T0P5US ) i <= i + 1'b1;

else begin rSIO <= rData[ (i >>

1) ]; rSCLK <= 1'b0; end

2, 4, 6, 8, 10, 12, 14, 16 : if( Count1 == T0P5US ) i <= i + 1'b1;

else begin rSCLK <= 1'b1; end

17 :

begin isOut <= 1'b0; i <= i + 1'b1; end

18, 20, 22, 24, 26, 28, 30, 32 : if( Count1 == T0P5US ) i <= i + 1'b1;

else begin rSCLK <= 1'b1; end

19, 21, 23, 25, 27, 29, 31, 33 : if( Count1 == T0P5US ) begin i <= i + 1'b1; end

else begin rSCLK <= 1'b0; rData[ (i >> 1) - 9 ] <= SIO; end

34 :

begin rRST <= 1'b0; isOut <= 1'b1; i <= i + 1'b1; end

35 :

begin isDone <= 1'b1; i <= i + 1'b1; end

36 :

begin isDone <= 1'b0; i <= 6'd0; end

endcase

assign Read_Data = rData;

assign Done_Sig = isDone;

assign RST = rRST;

assign SCLK = rSCLK;

assign SIO = isOut ? rSIO : 1'bz;

endmodule

本文来源:https://www.bwwdw.com/article/g4lm.html

Top