发 帖  
原厂入驻New
[问答] 如何用乘加器(mac)实现150个数平方和?
986 FPGA
分享
这个模块是music算法中的协方差矩阵中的一部分。输入的150个数是16位的,得到的结果是32位。
自己也写了代码可是结果多加了一次第一个数的平方。顶层模块代码如下
  1. module rom_mac(
  2.         clk,
  3.         nrst,
  4.         result
  5. );


  6. input wire        clk;
  7. input wire        nrst;
  8. output wire        [31:0] result;

  9. wire        [8:0] SYNTHESIZED_WIRE_0;
  10. wire        [15:0] SYNTHESIZED_WIRE_3;
  11. wire clk_25;




  12. rom_x1        rom_x1_1(
  13.         .clock(clk_25),
  14.         .address(SYNTHESIZED_WIRE_0),
  15.         .q(SYNTHESIZED_WIRE_3));


  16. mac        mac_r11(
  17.         .clock0(clk),
  18.         .clock1(clk_25),
  19.         .dataa(SYNTHESIZED_WIRE_3),
  20.         .datab(SYNTHESIZED_WIRE_3),
  21.         .result(result),
  22.         .aclr0(~nrst)
  23.         );


  24. cnt        cnt_add(
  25.         .clk(clk_25),
  26.         .nrst(nrst),
  27.         .q(SYNTHESIZED_WIRE_0));

  28. pll pll_25(
  29.         .inclk0(clk),
  30.         .c0(clk_25)
  31.         );
  32. endmodule
复制代码
调用了quartus的ip核ALTMULT_ACCUM、rom:1-port和pll。
批注 2020-01-09 212215.png
mac配置
批注 2020-01-09 211922.png
rom配置
批注 2020-01-10 104704.png
pll配置

cnt模块代码如下
  1. module cnt(
  2. clk,
  3. nrst,
  4. q
  5. );

  6. input clk;
  7. input nrst;
  8. output q;

  9. reg [8:0] q;

  10. always@(posedge clk or negedge nrst)
  11. begin
  12.         IF(~nrst)
  13.                 q<=9'd0;
  14.         else
  15.                 q<=q+1;
  16. end
  17. endmodule
复制代码


仿真结果如下
批注 2020-01-09 210747.png
1
2020-1-10 10:57:28   评论 分享淘帖 邀请回答
3个回答
看仿真波形,rom地址为0的值440读取了两个时钟周期,由于mac与rom的读取处于同步状态,那么地址0的值就行进行了两次操作。
//------
我安装的QuartusII不知道为什么没有这个rom的IP,没法搭工程。
理论上讲这个IP应该还有一个使能信号才对。要不然rom一直处在读数的状态。
//------
假如rom无使能端口,那么改变mac的复位信号aclr,使它延后一个时钟周期,这样就跳过了初始时刻rom的第一个值。
例:
always@(posedge clk_25 or negedge nrst)
begin
   if(!nrst) aclr0<= 1;//aclr0<= ~nrst;
   else      aclr0<= 0;//aclr0<= ~nrst;
end
//------
归根结底,程序没有大问题。
主要是top层对某些关键信号的控制不太严谨。
最佳答案
2020-1-10 10:57:29 1 评论

举报

1 条评论
rom配置.png
上图中clken是控制rom使能信号。我又用signal tap进行了验证。
当clken低电平rom输出为0.png
rom成功没有输出.png
clken为1的图当时没截图情况相反,rom正常输出。
可以验证clken控制rom
  1. module rom_mac(
  2.         clk,
  3.         nrst,
  4.         result
  5. );


  6. input wire        clk;
  7. input wire        nrst;
  8. output wire        [31:0] result;

  9. wire        [8:0] SYNTHESIZED_WIRE_0;
  10. wire        [15:0] SYNTHESIZED_WIRE_3;
  11. wire clk_25;
  12. wire rom_en;

  13. assign rom_en = (nrst == 1'b1) ? 1'b1 : 1'b0;
  14.        


  15. rom_x1        rom_x1_1(
  16.         .clock(clk_25),
  17.         .address(SYNTHESIZED_WIRE_0),
  18.         .clken(rom_en),
  19.         .q(SYNTHESIZED_WIRE_3));


  20. mac        mac_r11(
  21.         .clock0(clk),
  22.         .clock1(clk_25),
  23.         .dataa(SYNTHESIZED_WIRE_3),
  24.         .datab(SYNTHESIZED_WIRE_3),
  25.         .result(result),
  26.         .aclr0(~nrst)
  27.         );


  28. cnt        cnt_add(
  29.         .clk(clk_25),
  30.         .nrst(nrst),
  31.         .q(SYNTHESIZED_WIRE_0));

  32. pll pll_25(
  33.         .inclk0(clk),
  34.         .c0(clk_25)
  35.         );
  36. endmodule
复制代码
用nrst信号控制clken得到仿真结果
正确计算.png
(此回答仅仅是自己的总结)





评分

参与人数 1积分 +5 收起 理由
卿小小_9e6 + 5 您的帖子很精彩,期待您分享的下一个帖子!

查看全部评分

2020-1-11 12:23:54 评论

举报

撰写答案

你正在撰写答案

如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
我要提问
关闭

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

快速回复 返回顶部 返回列表