在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4000|回复: 13

[求助] 关于fifo的问题(verilog)求高手帮助

[复制链接]
发表于 2018-4-30 23:01:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 c134 于 2018-5-1 08:59 编辑

我写了一个FIFO的程序宽度8bit深度为4,也就是使用2^4 * 8bit = 128bit内存。仿真后功能是正常的,但是QuartusII编译后却用了256bit内存。求高手帮忙看看是什么原因。

module fifo_sync(
input nRst_i,
input Clk_i,
input Wr_i,
input [7:0]Din_i,
input Rd_i,
output [7:0]Dout_o,
output Full_o,
output Empty_o,
output [8:0]Count_o
);

reg [7:0]memory[15:0];//FIFO的存储空间
reg [8:0]wr_addr_reg;//写地址
reg [8:0]rd_addr_reg;//读地址

wire [7:0]fifo_in_addr;
wire [7:0]fifo_out_addr;
wire [8:0]wr_nextaddr;
wire [8:0]rd_nextaddr;

//FIFO写的地址生成器
assign wr_nextaddr = (Wr_i && ~Full_o)?wr_addr_reg + 1'b1:wr_addr_reg;

always@(negedge nRst_i or posedge Clk_i)
begin
if(!nRst_i)
    wr_addr_reg <=9'b0;
else
    wr_addr_reg <= wr_nextaddr;
end

//FIFO数据的写入
assign fifo_in_addr = wr_addr_reg[7:0];

always@(posedge Clk_i)//写数据
begin
if(Wr_i & ~Full_o)
    memory[fifo_in_addr] <= Din_i;
else
    memory[fifo_in_addr] <= memory[fifo_in_addr];
end

//FIFO读的地址生成器
assign rd_nextaddr = (Rd_i && ~Empty_o)?rd_addr_reg + 1'b1:rd_addr_reg;

always@(negedge nRst_i or posedge Clk_i)
begin
if(!nRst_i)
    rd_addr_reg <= 9'b0;
else
    rd_addr_reg <= rd_nextaddr;
end

//FIFO数据的输出
assign fifo_out_addr  = rd_addr_reg[7:0];
assign Dout_o = memory[fifo_out_addr];//读数据
//FIFO空
assign Empty_o = (wr_addr_reg == rd_addr_reg);
//FIFO满
assign Full_o = (wr_addr_reg == {~rd_addr_reg[8], rd_addr_reg[7:0]});
//计数器
assign Count_o = wr_addr_reg - rd_addr_reg;

endmodule

1.png

请高手帮忙看看是什么原因,谢谢
 楼主| 发表于 2018-5-1 09:01:07 | 显示全部楼层
自己顶一下,求帮助
发表于 2018-5-1 09:33:29 | 显示全部楼层
memory和addr的位宽都有问题。
reg [7:0] memory[3:0]
wire [3:0] fifo_in_addr
 楼主| 发表于 2018-5-1 09:45:44 | 显示全部楼层
程序宽度8bit深度为2^4,也就是使用2^4 * 8bit = 128bit内存。
reg [7:0]memory[15:0];//FIFO的存储空间
没有问题吧
发表于 2018-5-1 11:36:56 | 显示全部楼层
回复 4# c134


  2^4是指的深度一共为16,对吧?如果你的地址是每次+1操作,按照你这个写法,[7:0]的地址应该是从0一直到255,共计256个地址。。。
 楼主| 发表于 2018-5-1 16:23:49 | 显示全部楼层
本帖最后由 c134 于 2018-5-1 16:31 编辑

回复 5# xiaxiasha

确实代码有点问题,我进行了修改。FIFO的程序宽度8bit深度为16,也就是使用16 * 8bit = 128bit内存。但是QuartusII编译后却用了256bit内存。您再帮我看看是什么原因。

module fifo_sync(
input nRst_i,
input Clk_i,
input Wr_i,
input [7:0]Din_i,
input Rd_i,
output [7:0]Dout_o,
output Full_o,
output Empty_o,
output [4:0]Count_o
);

reg [7:0]memory[0:15];//FIFO的存储空间
reg [4:0]wr_addr_reg;//写地址0-15,最高位用于辅助判定空或满
reg [4:0]rd_addr_reg;//读地址0-15,最高位用于辅助判定空或满

wire [3:0]fifo_in_addr;
wire [3:0]fifo_out_addr;
wire [4:0]wr_nextaddr;
wire [4:0]rd_nextaddr;

//FIFO写的地址生成器
assign wr_nextaddr = (Wr_i && ~Full_o)?wr_addr_reg + 1'b1:wr_addr_reg;

always@(negedge nRst_i or posedge Clk_i)
begin
if(!nRst_i)
    wr_addr_reg <=5'b0;
else
    wr_addr_reg <= wr_nextaddr;
end

//FIFO数据的写入
assign fifo_in_addr = wr_addr_reg[3:0];

always@(posedge Clk_i)//写数据
begin
if(Wr_i & ~Full_o)
    memory[fifo_in_addr] <= Din_i;
else
    memory[fifo_in_addr] <= memory[fifo_in_addr];
end

//FIFO读的地址生成器
assign rd_nextaddr = (Rd_i && ~Empty_o)?rd_addr_reg + 1'b1:rd_addr_reg;

always@(negedge nRst_i or posedge Clk_i)
begin
if(!nRst_i)
    rd_addr_reg <= 5'b0;
else
    rd_addr_reg <= rd_nextaddr;
end

//FIFO数据的输出
assign fifo_out_addr  = rd_addr_reg[3:0];
assign Dout_o = memory[fifo_out_addr];//读数据
//FIFO空
assign Empty_o = (wr_addr_reg == rd_addr_reg);
//FIFO满
assign Full_o = (wr_addr_reg == {~rd_addr_reg[4], rd_addr_reg[3:0]});
//计数器
assign Count_o = wr_addr_reg - rd_addr_reg;

endmodule
请看一下我编译后的结果,为什么内存被分配为2块,这两块各使用128bit内存。
2.png
发表于 2018-5-1 23:34:22 | 显示全部楼层
读、写逻辑都有问题,你画下状态机看看。
 楼主| 发表于 2018-5-2 09:50:32 | 显示全部楼层
本帖最后由 c134 于 2018-5-2 11:03 编辑

回复 7# siriux

附上测试文件和仿真截图,功能正常。不知道您说的读写有问题指的是什么?读写问题会导致编译时分配内存翻倍吗?请指教,谢谢。
`define CYCLE
10

module fifo_sync_vlg_tst();

reg nRst_i;
reg Clk_i;
reg Wr_i;
reg [7:0]Din_i;
reg Rd_i;
wire [7:0]Dout_o;
wire Empty_o;
wire Full_o;
wire [4:0]Count_o;

fifo_sync fifo(
.nRst_i(nRst_i),
.Clk_i(Clk_i),
.Wr_i(Wr_i),
.Rd_i(Rd_i),
.Din_i(Din_i),
.Dout_o(Dout_o),
.Full_o(Full_o),
.Empty_o(Empty_o),
.Count_o(Count_o)
);

task FIFO_WRITE;
input [7:0]dt;
begin
#1 Din_i = dt;
@(posedge Clk_i);
#1 Wr_i = 1;
@(posedge Clk_i);
#1 Wr_i = 0;
end
endtask

task FIFO_READ;
begin
@(posedge Clk_i);
#1 Rd_i = 1;
@(posedge Clk_i);
#1 Rd_i = 0;
end
endtask

always #(`CYCLE/2)  Clk_i = ~Clk_i;

initial
begin
nRst_i = 1'b1;
Clk_i = 1'b0;
Wr_i = 1'b0;
Rd_i = 1'b0;

#(`CYCLE) nRst_i = 1'b0;
#(`CYCLE) nRst_i = 1'b1;
#(`CYCLE)

#(`CYCLE*2) FIFO_WRITE(16'h1111);
#(`CYCLE*2) FIFO_WRITE(16'h2222);
#(`CYCLE*2) FIFO_WRITE(16'h3333);
#(`CYCLE*2) FIFO_WRITE(16'h4444);

#(`CYCLE*2) FIFO_WRITE(16'h5555);
#(`CYCLE*2) FIFO_WRITE(16'h6666);
#(`CYCLE*2) FIFO_WRITE(16'h7777);
#(`CYCLE*2) FIFO_WRITE(16'h8888);

#(`CYCLE*2) FIFO_WRITE(16'h9999);
#(`CYCLE*2) FIFO_WRITE(16'hAAAA);
#(`CYCLE*2) FIFO_WRITE(16'hBBBB);
#(`CYCLE*2) FIFO_WRITE(16'hCCCC);

#(`CYCLE*2) FIFO_WRITE(16'hDDDD);
#(`CYCLE*2) FIFO_WRITE(16'hEEEE);
#(`CYCLE*2) FIFO_WRITE(16'hFFFF);
#(`CYCLE*2) FIFO_WRITE(16'h0000);

#(`CYCLE*2)

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_WRITE(16'h0001);
#(`CYCLE*2) FIFO_WRITE(16'h0002);
#(`CYCLE*2) FIFO_WRITE(16'h0003);
#(`CYCLE*2) FIFO_WRITE(16'h0004);

#(`CYCLE*2) FIFO_WRITE(16'h0005);
#(`CYCLE*2) FIFO_WRITE(16'h0006);
#(`CYCLE*2) FIFO_WRITE(16'h0007);
#(`CYCLE*2) FIFO_WRITE(16'h0008);

#(`CYCLE*2) FIFO_WRITE(16'h0009);
#(`CYCLE*2) FIFO_WRITE(16'h000A);
#(`CYCLE*2) FIFO_WRITE(16'h000B);
#(`CYCLE*2) FIFO_WRITE(16'h000C);

#(`CYCLE*2) FIFO_WRITE(16'h000D);
#(`CYCLE*2) FIFO_WRITE(16'h000E);
#(`CYCLE*2) FIFO_WRITE(16'h000F);
#(`CYCLE*2) FIFO_WRITE(16'h0010);

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();


#(`CYCLE*2) FIFO_WRITE(16'h0011);
#(`CYCLE*2) FIFO_WRITE(16'h0012);
#(`CYCLE*2) FIFO_WRITE(16'h0013);
#(`CYCLE*2) FIFO_WRITE(16'h0014);

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();
#(`CYCLE*2) FIFO_READ();

#100 $stop;
end

endmodule

2.png
发表于 2018-5-2 11:27:39 | 显示全部楼层
应该是你的地址多了一位,用来判断空满,所以就是要占用128*2bit 的内存了。
 楼主| 发表于 2018-5-2 12:00:32 | 显示全部楼层
回复 9# chb734812620

我开始也认为有可能是这个问题,但是定义内存大小应该以“reg [7:0]memory[0:15];”为准吧。如果我越界操作的话应该报错才对。我也曾经试着把用来判断空满的寄存器和读写指针寄存器分开写,编译后结果是一样的。
为什么编译时需要分成2块128bit内存,为什么不是一块256bit内存?




求高手指条明路啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-23 23:14 , Processed in 0.023023 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表