特权同学

MCU与液晶控制模块通讯仿真

0
阅读(13597)

做一个CPLD液晶控制模块,其中CPLD与MCU的通信协议如下:

x_cnt[1..640]:ADDR[9..0] VGA显示行坐标 //对应SRAM的ADDR[9..0]

y_cnt[1..480]:ADDR[8..0] VGA显示列坐标 //对应SRAM的ADDR[18..10]

MCU和CPLD接口:

CS: CPLD片选

RS: RS=0写命令,RS=1写数据

RD: RD=0,写选通

WR:WR=0,读选通

DB[7..0]: 数据总线(写入数据时低3bit有效)

8bit命令寄存器CMD_REG使用说明:

CMD_REG[2..0] =000:写入x坐标地址addr[7:0]

=001:写入x坐标地址addr[9:8]

=010:写入y坐标地址addr[7:0]

=011:写入y坐标地址addr[8]

=100:写入显示数据,x坐标、y坐标地址不变

=101:写入显示数据,x坐标地址增1,y坐标地址不变

(当x坐标写满,回到1地址,同时y坐标地址自动加1)

=110:写入显示数据,y坐标地址增1,x坐标地址不变

(y坐标地址写满后,需要软件送地址复位)

CMD_REG[3] =1:开显示

=0:关显示

CMD_REG[7..4] 保留

现在要做一个仿真实验,看看CPLD的设计是否符合要求,到达预定目的。Testbench的设计即仿真模块分为三个部分:

//时钟复位部分//这个部分产生时钟源,以及上电的复位模拟

//模拟激励部分//这个部分产生激励信号,模拟MCU向CPLD发送命令/地址/数据

//自动验证部分//这个部分时产生(自动)验证机制,对通信的结果进行验证

时钟复位如下代码实现:

initial begin

rst_n = 0;//复位

#100;

rst_n = 1;//复位结束

end

initial begin

clk = 0;

forever

#10 clk = ~clk; //产生20ns的时钟信号

End

模拟激励部分:

实现功能如下:

  • 写入x坐标地址为1,y坐标地址为1
  • 在写入地址后x,y地址不自增模式下连续写入0,1,2,3,4四个数据
  • 在写入地址后x地址自增,y地址不自增模式下连续写入0,1,2,3,4四个数据
  • 在写入地址后x地址不自增,y地址自增模式下连续写入0,1,2,3,4四个数据

自动验证部分:

1、观察波形(不能算做自动验证,比较常规的观察方法,在大模块的设计中时无法进行RTL设计仿真验证)

2、使用如下代码:

initial begin

$monitor($time,," sram_wr_data=%d, x_addr=%d, y_addr=%d",

sram_wr_data,sram_wr_addr[9:0],sram_wr_addr[18:10]);

end

只要sram_wr_data,sram_wr_addr[9:0],sram_wr_addr[18:10]三个数据的任意一个发生变化,modelsim的命令窗口就会更新一次数据。

在modelsim命令窗口观察到如下数据:

# 0 sram_wr_data=x, x_addr= x, y_addr= x

run -all

# 1270 sram_wr_data=x, x_addr= X, y_addr= x

# 2470 sram_wr_data=x, x_addr= 1, y_addr= x

# 3670 sram_wr_data=x, x_addr= 1, y_addr= X

# 4870 sram_wr_data=x, x_addr= 1, y_addr= 1

# 6070 sram_wr_data=0, x_addr= 1, y_addr= 1

# 6670 sram_wr_data=1, x_addr= 1, y_addr= 1

# 7270 sram_wr_data=2, x_addr= 1, y_addr= 1

# 7870 sram_wr_data=3, x_addr= 1, y_addr= 1

# 8470 sram_wr_data=4, x_addr= 1, y_addr= 1

# 9670 sram_wr_data=0, x_addr= 1, y_addr= 1

# 9710 sram_wr_data=0, x_addr= 2, y_addr= 1

# 10270 sram_wr_data=1, x_addr= 2, y_addr= 1

# 10310 sram_wr_data=1, x_addr= 3, y_addr= 1

# 10870 sram_wr_data=2, x_addr= 3, y_addr= 1

# 10910 sram_wr_data=2, x_addr= 4, y_addr= 1

# 11470 sram_wr_data=3, x_addr= 4, y_addr= 1

# 11510 sram_wr_data=3, x_addr= 5, y_addr= 1

# 12070 sram_wr_data=4, x_addr= 5, y_addr= 1

# 12110 sram_wr_data=4, x_addr= 6, y_addr= 1

# 13270 sram_wr_data=0, x_addr= 6, y_addr= 1

# 13310 sram_wr_data=0, x_addr= 6, y_addr= 2

# 13870 sram_wr_data=1, x_addr= 6, y_addr= 2

# 13910 sram_wr_data=1, x_addr= 6, y_addr= 3

# 14470 sram_wr_data=2, x_addr= 6, y_addr= 3

# 14510 sram_wr_data=2, x_addr= 6, y_addr= 4

# 15070 sram_wr_data=3, x_addr= 6, y_addr= 4

# 15110 sram_wr_data=3, x_addr= 6, y_addr= 5

# 15670 sram_wr_data=4, x_addr= 6, y_addr= 5

# 15710 sram_wr_data=4, x_addr= 6, y_addr= 6

# Break key hit

$time是时间命令,就是#后的第一列为仿真的绝对时间,单位ns,后面是仿真过程中的数据变化。

上面的两种验证方法还不是做到真正意义上的自动验证。因为这个模块比较简单,所以做到这个程度已经能够很好了验证了RTL设计的正确性。如果更大的系统模块,应该时准备好一组正确数据和经过RTL代码的输出数据比较,然后在屏幕直接送出是否出错的提示就可以了。

Baidu
map