原创 双向口采用纯组合逻辑产生的组合回环

2012-4-18 22:56 2868 20 20 分类: FPGA/CPLD

这是一个RAM的代码:

me :使能信号

io: 控制输入输出 io=1接收,io=0输出

marL:地址寄存使能信号

/*----------------------------------------------------------*/

module ram_mar( clk , io , me , marL , bus ) ;

input clk,io,me;  //me=1,io=1接收数据
input marL;
inout [ 7 : 0 ] bus ;

reg [ 7 : 0 ] addr_r = 8'b0 ;

always@(posedge clk)
begin
        if ( marL ) begin
             addr_r <= bus ;
        end
        else begin
             addr_r <= addr_r;
        end
end

reg [ 7 : 0 ]  ramr [ 255 : 0 ] ;

always @(addr_r or me or io or bus)
begin
        if ( me & io ) begin
              ramr[ addr_r ] <= bus ;
        end
        else begin
              ramr[ addr_r ] <= ramr[addr_r] ;
        end
end

assign bus = ( me & ( ~io ) ) ? ramr[addr_r] : 8'bzzzz_zzzz ;

endmodule

/*----------------------------------------------------------*/

编译时没有警告, 综合后出现如下警告:

Warning: Latch ramr~1360 has unsafe behavior
     Warning: Ports D and ENA on the latch are fed by the same signal addr_r[7]

分析语法肯定没问题 ,第一个always也肯定没问题,问题就出在第二个always !

在第二个always中没有Clk,也就是纯组合逻辑!

因为bus是双向口,从RAM ---> bus ---> RAM 形成一个大的组合和回环!

这样的组合设计本身很不好,这次综合器碰巧优化出了正确的电路,下次可不一定!

而且从设计的可靠性、提高工作时钟来考虑,都应该尽量采用同步时序。

修改后的代码如下:

/*-------------------------------------------------------*/

module ram_mar(clk,io,me,marL,bus);
input clk,io,me;//me=1,io=1接收数据
input marL;
inout [7:0] bus;

reg [ 7 : 0] addr_r = 0 ;
always@(posedge clk)begin
if ( marL )begin
    addr_r<=bus;
    end
else begin
    addr_r<=addr_r;
    end
end

//(*ramstyle="logic"*)
reg [7:0] ramr [255:0];

always@( posedge clk)begin
if ( me & io) begin
    ramr[ addr_ r] <= bus ;
    end
else begin
    ramr[ addr_r ] <= ramr[ addr_r ] ;
    end
end
assign bus=( me & ( ~io ) ) ? ramr[addr_r] : 8'bzzzz_zzzz ;

endmodule

/*---------------------------------------------------*/

两个代码在Quartus II下综合出的电路一模一样,不知道在Synplify下会不会有不一样的结果,感兴趣的话可以试一下。下面是RTL图:

组合回环.jpg

文章评论0条评论)

登录后参与讨论
我要评论
0
20
关闭 站长推荐上一条 /2 下一条