取消
显示结果 
搜索替代 
您的意思是: 
Highlighted
Visitor
Visitor
133 次查看
注册日期: ‎07-25-2020

新手求助,在implement阶段报Multiple Driver的错误,不知道怎么分析和解决

我是想做一个通过串口发送指令来控制两个led闪烁的功能。发送的指令为每个灯两个字节,大概格式是这样0xAA 0xAA 0xBB 0xBB。0xAA 0xAA是控制第一个灯的指令,取值范围为1-5000(十进制)和0xffff.1-5000表示控制led闪烁的时间间隔为1ms-5s。0xffff则表示不闪烁。0xBB 0xBB同理。

因为一些其他的原因,我需要先存储接收到的指令到一个FIFO里面,再从这个FIFO中读取出指令并实现控制led的功能。

控制led的模块代码如下(因为是新手,所以代码写得也比较乱):

`timescale 1ns / 1ps
module TwoLed(
input clk50mhz,//clk
input rstn,
input OneCMDEnd,
input [7:0] CMDByte,
input FIFOempty,
output FIFORdEn,//读FIFO使能信号
output led0shine,
output led1shine,
output reg [7:0] ledstate,
output reg TransmitterWrEn
);

reg CMDEnd0;
reg CMDEnd1;
wire CMEEndUpEdge;
reg StartStateMa;//接收到一个OneCMDEnd的上升沿,表示一条指令接收完毕,状态机开始运作,从FIFO读取指令。

reg FIFORdEn;
reg [2:0] FIFORdCnt;//从FIFO读取的命令的字节数

reg [15:0] cnt;//由于这里用的时钟为50mhz,其他模块都是用的baud16x,时钟不匹配,所以在从FIFO
//读取数据的时候需要分频

reg [2:0] state;
reg [15:0] LED0CMD;//用来存储两个LED各自的接收的命令的数值
reg [15:0] LED1CMD;

reg[31:0] LED0Divider;//最大的分频倍数是 5s 0.2hz 50mhz/0.2hz = 25 000 0000 需要32位才装得下
reg[31:0] LED1Divider;
reg [31:0] led0cnt;//用来分频的计数器
reg [31:0] led1cnt;
reg led0shine;
reg led1shine;
reg [7:0] led0state;
reg [7:0] led1state;

reg [31:0] ledstateTranscnt;//
reg startTransledstate;//表示处于给电脑端回复led状态的过程中

 

//检测OneCMDEnd的上升沿,启动状态机的运作
always@(posedge clk50mhz or negedge rstn) begin
if(!rstn)begin
CMDEnd0 <= 0;
CMDEnd1 <= 0;
end
else begin
CMDEnd0 <= OneCMDEnd;
CMDEnd1 <= CMDEnd0;
end
end
assign CMEEndUpEdge=CMDEnd0 && (!CMDEnd1);

//状态机的启动
always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
StartStateMa <= 0;
FIFORdEn <= 0;
end
else begin
if(CMEEndUpEdge == 1'b1) begin StartStateMa<=1; FIFORdEn <= 1; FIFORdCnt <= 0; end
else if(FIFORdCnt>=4) begin StartStateMa<= 0; FIFORdEn <= 0; end //FIFORdCnt >= 4说明读取了一条完整的指令
end
end

//处理cnt 如果状态机开始运行i.e. StartStateMa为1,那么就要用cnt来计数,确定何时给出RdEn信号
always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
cnt <= 0;
end
else if(StartStateMa == 1'b1)begin
cnt <= cnt + 1;
end
else cnt <= 0;//状态机一轮执行完毕或者处于初始状态,也就是状态机未运行的时候,保持cnt为0
end

//状态机的状态转换
always@(posedge clk50mhz or negedge rstn) begin
if (!rstn) begin
state <= 0;//初始状态
FIFORdCnt <= 0;
LED0CMD <= 0;
LED1CMD <= 0;
end
else if((StartStateMa == 1'b1)&& (!FIFOempty)) begin
case(cnt) //由于Standard FIFO和另一种模式,读取的时候数据可能慢一个周期,。要注意这个地方可能会出问题
16'd325:begin LED0CMD[15:8] <= CMDByte; FIFORdCnt <= 1; state<= 1; end //接收完第一个字节
16'd650:begin LED0CMD[7:0] <= CMDByte; FIFORdCnt <= 2; state<= 2;end //接收完第2个字节
16'd975:begin LED1CMD[15:8] <= CMDByte; FIFORdCnt <= 3; state<= 3;end //接收完第3个字节
16'd1300:begin LED1CMD[7:0] <= CMDByte; FIFORdCnt <= 4; state<= 4; end//接收完第4个字节
endcase
end
end
//接收完命令之后的处理。通过命令来改变分频的频率,得到输出到LED的信号
always@(posedge clk50mhz or negedge rstn) begin
if (!rstn) begin
LED0Divider<=0;
LED1Divider<=0;
led0state <= 8'hff;
led1state <= 8'hff;
end
else if(state ==4) begin //表明命令都已经读取了
led0cnt <= 0;
led1cnt <= 0;
led0shine <= 0;
led1shine <= 0;
startTransledstate <= 1;
ledstateTranscnt <= 0;
if(LED0CMD == 16'hFFFF)begin
LED0Divider <= 0;//表示不闪烁
led0state <= 8'hff;
end
else begin
LED0Divider <= LED0CMD * 50000;//不是FFFF,计算得到分频背书
led0state <= 8'h01;
end
if(LED1CMD == 16'hFFFF) begin
LED1Divider <= 0;
led1state <= 8'hff;
end
else begin
LED1Divider <= LED1CMD * 50000;
led1state <= 8'h01;
end
state <= 0;
end
end

//分频产生控制led闪烁的信号.
always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
led0cnt <= 0;
end
else begin
if(LED0Divider == 0) led0cnt <=0 ;
else led0cnt <= led0cnt + 1 ;
end
end

always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
led0shine <= 0;
end
else if(led0cnt == LED0Divider/2) begin
led0shine <= 1;
end
else if(led0cnt >= LED0Divider) begin
led0shine<= 0;
led0cnt <= 0;
end
end
always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
led1cnt <= 0;
end
else begin
if(LED1Divider == 0) led1cnt <=0 ;
else led1cnt <= led1cnt + 1 ;
end
end

always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
led1shine <= 0;
end
else if(led1cnt == LED1Divider/2) begin
led1shine <= 1;
end
else if(led1cnt >= LED1Divider) begin
led1shine<= 0;
led1cnt <= 0;
end
end

//处理回复信息,回复给电脑端,当前两个灯的状态
always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
ledstate <= 8'hFF;
TransmitterWrEn <= 0;
end
else case(ledstateTranscnt)
32'd0: TransmitterWrEn<=1;
32'd325:begin TransmitterWrEn<= 0; ledstate<= led0state;end
32'd52650: TransmitterWrEn <= 1;//325*162=52650,第一个led的状态传输完成
32'd52975:begin ledstate<= led1state;TransmitterWrEn <= 0;end
32'd105300:startTransledstate <= 0;//324*325=105300表示第二个led的状态也传输完毕
endcase
end

always@(posedge clk50mhz or negedge rstn) begin
if(!rstn) begin
ledstateTranscnt <= 0;
end
else if(startTransledstate == 1) begin //处于传输状态时 cnt一直加1
ledstateTranscnt <= ledstateTranscnt + 1;
end
else ledstateTranscnt <= 0;
end
endmodule

然后implement的时候,在OptDesign阶段报了Multiple Driver Net的错误,自己也不知道该解决,求帮助。如果能说明一下分析的思路和过程就感激不尽了。2020-08-01-20-50-21.png2020-08-01-21-41-41.png

 

0 项奖励
2 回复数
Highlighted
Xilinx Employee
Xilinx Employee
85 次查看
注册日期: ‎02-28-2019

重复帖,已在这个帖子中回复https://forums.xilinx.com/t5/Vivado/%E6%96%B0%E6%89%8B%E6%B1%82%E5%8A%A9-%E5%9C%A8implement%E7%9A%84Opt-design%E9%98%B6%E6%AE%B5%E6%8A%A5Multiple-Driver-%E4%B8%8D%E7%9F%A5%E9%81%93%E6%80%8E%E4%B9%88%E5%88%86%E6%9E%90%E5%92%8C%E8%A7%A3%E5%86%B3/m-p/11...

-------------------------------------------------------------------------
Don't forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 项奖励
Highlighted
Explorer
Explorer
33 次查看
注册日期: ‎12-01-2017

if(CMEEndUpEdge == 1'b1) begin StartStateMa<=1; FIFORdEn <= 1; FIFORdCnt <= 0; end

case(cnt) //由于Standard FIFO和另一种模式,读取的时候数据可能慢一个周期,。要注意这个地方可能会出问题
16'd325:begin LED0CMD[15:8] <= CMDByte; FIFORdCnt <= 1; state<= 1; end //接收完第一个字节
16'd650:begin LED0CMD[7:0] <= CMDByte; FIFORdCnt <= 2; state<= 2;end //接收完第2个字节
16'd975:begin LED1CMD[15:8] <= CMDByte; FIFORdCnt <= 3; state<= 3;end //接收完第3个字节
16'd1300:begin LED1CMD[7:0] <= CMDByte; FIFORdCnt <= 4; state<= 4; end//接收完第4个字节
endcase

赋值条件不互斥,有可能同时赋值,综合器不知道你的设计目的,没法把硬件描述语言所描述的设计综合成布局布线。

---/\/\/\/\/\/\/\---
Always Online
0 项奖励