我对verilog(VHDL用户)比较陌生,为了提高我的技能,我使用verilog构建我的测试环境(我的QC使用他们自己的env)。
在我的环境中,我模仿一个强制线上随机刺激的主人(i2c master)。
因为我并不真的想要使用一位真正的大师而只想要一个表现良好的大师。 master,我创建了以下宏来为我提供i2c通信:
`define writeChipId(addr)\
sda = 1\
#7500 sda = addr[3];\
#2500 sda = addr[2];\
#2500 sda = addr[1];\
#2500 sda = addr[0];\
#2500;
`define writeData(data)\
sda = data[7]\
#2500 sda = data[6];\
#2500 sda = data[5];\
#2500 sda = data[4];\
#2500 sda = data[3];\
#2500 sda = data[2];\
#2500 sda = data[1];\
#2500 sda = data[0];\
#2500 sda = 1;\
#2500; // time for the slave to answer
`define readData\
#sda = 1\
#20000 sda = 0;\
#2500; // master always answer ACK
我的问题是,当我尝试使用这些宏时,我得到编译错误(使用modelsim)说我有语法错误,我有意想不到的' ['应该是&#39 ;;'使用chipID宏并有意想不到的'#'应该是&#39 ;;'使用read \ write宏时。
我尝试(和失败)的用法是
`writeChipId(`chipID)
和
`writeData(rndData)
和
`readData
最后,但并非最不重要:如果我在代码中没有使用宏写相同的行,它会完美编译(仅在一个地方尝试过,不想在其他12个地方执行此操作,而不是我需要这些宏...)
任何人都有线索是什么问题?我一直试图玩这些没有运气的宏,并且还证实他们没有卡在中间的空白区域。事先感谢所有回复者
修改
我忘了说的东西:当我拿宏并删除输入并使用const值而不是输入时,它工作正常。
答案 0 :(得分:2)
`define
的语法在宏标识符/参数之后需要一个空格。
`define writeChipId(addr) \
sda = 1;\
#7500 sda = addr[3];\
#2500 sda = addr[2];\
#2500 sda = addr[1];\
#2500 sda = addr[0];\
#2500;
正如Greg指出的那样,这确实需要使用task
。
task writeChipId(input [3:0] addr);
sda = 1;
#7500 sda = addr[3];
#2500 sda = addr[2];
#2500 sda = addr[1];
#2500 sda = addr[0];
#2500;
endtask
答案 1 :(得分:0)
好的,解决方案发现: 每个宏的第一行也应该有分号(;),同样 - 在verilog上使用chipID的参数很难,这可以通过将输入放入reg并使用reg的位来解决。
我上次使用宏时没有遇到过这个问题,因为我犯了另一个错误 - 我将常量的宏定义为分号(意为`define ADD 32'h0;
),当我使用它时它插入了;在线,似乎没问题。