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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 3263|回复: 5

[求助] 请教一个verilog编程问题 (更新)

[复制链接]
发表于 2013-5-23 20:00:13 | 显示全部楼层 |阅读模式
500资产
本帖最后由 yong19891101 于 2013-5-23 22:50 编辑

由于上个问题没有描述清楚,这里详细说一下: saple.jpg
这是我想要实现的结构,(后面的那个MEMi存储器大家先不要管)MEMr(深度128)存储器分为两部分上半部分为大于0的整数,下半部分为0,所有数的和为128。取到为0的数 就结束读取了。关键就是要得到addrb这个地址。可以这样来理解,上半部分大于0的是需要复制的数据,下半部分等于0的数据时需要被复制的数据覆盖的。复制次数等于1的数据只要覆盖到他自己的地址,大于1的数据还要复制到MEMr底部为0的位置,比如第一个数为4,则要把4复制4次,首先复制到他自己对应的地址0,然后复制到底部地址127、126、125,然后读出下一个数。。。
比如MEMr前四个数为3、2、1、4,则其对应的addrb时序如下
MEMr            3                     、 2      、 1         、 4
addrb           0   127   126      、 1     、125      、2     124  123  122
这就是我想要的结果。得到的addrb地址最后就是0到127。
我的思路如下:
先给一个周期的买抽pulse启动en1信号,同时启动r_up计数器核MEMr存储器,从rMEM读出第一个数x后,先判断x是否大于1,如大于1,则把x-1送入k_down计数器,如等于1,则马上启动en1信号 读出rMEM下一个数
k_down计数器的输出k_out等于1时启动en1信号
en2信号基本就是en1的取反了。

我写的程序如下(MEMr存储器输出没有加寄存器):

module sample1(clk,set,en1,en2,ena,pulse,r_up,d_down,r_out,k_out,addrb,wea,addra,dina
    );


input clk,set,wea,pulse,ena;

input[6:0]addra,dina;

output [6:0]r_up,d_down,addrb,r_out(存储器输出),k_out;

output en1,en2,r_ready,down_en,up_en;

reg [6:0]r_up,d_down,addrb,k_out;


//counter_r_up

always@(posedge clk)
  begin
        if(set)           begin
             r_up<=0;
           end

        else if(en1==1)
          begin
           r_up<=r_up+1;
           end
end

    //counter_d_down

always@(posedge clk)

   begin

     if(set)
          begin
          d_down<=7'd127;
         end
      else if(en2==1)
        begin
           d_down<=d_down-1;
          end
  end


  //选择器

always@(posedge clk)

   begin
       if(set)
           begin
                addrb<=0;
          end
        else if(en2==1)
               begin
             addrb<=d_down;
                end
         else
            begin
              addrb<=r_up;
           end

end
  //en1和en2信号赋值
  assign    en1=((r_out==1)||pulse||(k_out==1))?1:0;
  assign     en2=(r_out>1)&&(k_out!==1)&&(!pulse);




  //counter_k_down #######感觉这部分有问题,这里的en1信号应该延迟一个周期,
  always@(posedge clk)
     begin
        if(set)
           begin
                k_out<=0;
           end

        else if(en1==1)
           begin
                k_out<=r_out-1;
           end

        else if(en2==1)
           begin
            k_out<=k_out-1;

             end
  end



  //rMEM 存储器例化
rMEM MYrMEM (
  .clka(clk), // input clka
  .ena(ena), // input ena
  .wea(wea), // input [0 : 0] wea
  .addra(addra), // input [6 : 0] addra
  .dina(dina), // input [6 : 0] dina
  .clkb(clk), // input c // input [6 : 0] addra
  .rstb(set), // input rstb
  .enb(en1), // input enb
  .addrb(addrb), // input [6 : 0] addrb
  .doutb(r_out) // output [6 : 0] doutb
);


endmodul


我看到有文献说这里的k_down计数器是用的异步mask标记信号,说是流水线读出的,个人感觉用同步很难实现流水线输出。希望有大神帮忙,下面这个图是文献给出的仿真图,他用的存储器深度为1024。不知道我描述清楚了没有
1.jpg

最佳答案

查看完整内容

根据你贴的波形,代码描述如下,代码没有仿真,你可以根据波形再研究研究 //en1 count_up wire [6:0]mask_data; wire memr_rden = pulse | (mask_data==1); wire en1=memr_rden; reg [6:0]count_up; reg [6:0]count_down; reg [6:0]count_k; reg memr_rd_dat_ready; always@(posedge clk)begin if(rst) count_up
发表于 2013-5-23 20:00:14 | 显示全部楼层
根据你贴的波形,代码描述如下,代码没有仿真,你可以根据波形再研究研究
//en1 count_up
wire [6:0]mask_data;
wire memr_rden = pulse | (mask_data==1);
wire en1=memr_rden;
reg [6:0]count_up;
reg [6:0]count_down;
reg [6:0]count_k;
reg memr_rd_dat_ready;
always@(posedge clk)begin
if(rst)
    count_up <= 'h0;
else if(en1)
    count_up <= count_up + 1;
end
      
always@(posedge clk)begin
if(rst)
    memr_rd_dat_ready <= 'h0;
else
    memr_rd_dat_ready <= memr_rden;
end
//en2 count_down
wire en2 = mask_data > 1;
assign mask_data = memr_rd_dat_ready ? memr_out : count_k;

always@(posedge clk)begin
if(rst)
    count_down <= 'h7f;
else if(en2)
    count_down <= count_down - 1;
end
//count K
always@(posedge clk)begin
if(rst)
    count_k <= 'ho;
else if(memr_rd_dat_ready)
    count_k <= memr_out - 1;
else if(count_k > 1)
    count_k <= count_k - 1;
end
wire [6:0]addrb = memr_rden ? count_up : count_down;
发表于 2013-5-23 23:21:40 | 显示全部楼层
这是个什么功能啊?
 楼主| 发表于 2013-5-24 10:36:49 | 显示全部楼层
回复 2# HADIST
简单的说 就是有两个存储器 rMEM和pMEM ,rMEM存储器储存了PMEM对应数据应该复制的次数,总复制次数等于存储器深度。且rMEM上半部分为大于0的整数,下半部分为0,这说明需要把PMEM上半部分数据要复制,下半部分要抛弃,从而要把pMEM的上部分的数据读出来然后复制到需要抛弃的位置,这样一来就需要控制pMEM的地址addrb,这个地址就要根据rMEM的数据来确定。
比如说rMEM第一个数据为4,那说明pMEM第一个数据要复制4次,第一次复制到自己本身的位置,剩下三次复制到底部需要抛弃的位置,即127、126、125.所以如果rMEM前四个数据为4、3、2、1,则其对应addrb的时序就是
rMEM  4     4       4       4       3       3        3          2          2        1
addrb 0   127   126    125      1    124      123      2         122      3
这样说明白了吗
 楼主| 发表于 2013-5-24 11:07:20 | 显示全部楼层
本帖最后由 yong19891101 于 2013-5-24 20:20 编辑

回复 3# ivor_kandy
我按你说的搞了一遍  稍微你改了以下 数据都对了  就是和理论的那个仿真图相比,所有数据整体提前了一个周期  要是能和延迟一个就好了 不过已经很不错了 非常感谢 高手啊!!!!module sample1(clk,set,ena,pulse,counter_up,counter_down,rmem_out,counter_k,addrb,wea,addra,dina,
   up_en,down_en,mask_data,rmem_rden,rdata_ready);

  input clk,set,wea,pulse,ena;
  input[6:0]addra,dina;
  output [6:0]counter_up,counter_down,addrb,rmem_out,counter_k,mask_data,rdata_ready;
  output down_en,up_en,rmem_rden;
  reg [6:0]counter_up,counter_down,counter_k;
  reg  rdata_ready;
  reg [6:0]addrb;
  wire [6:0]mask_data;


    assign  rmem_rden=pulse|(mask_data==1);
    assign  up_en=rmem_rden;
    assign  down_en=(mask_data>1);
  //counter_r_up
  always@(posedge clk)
    begin
     if(set)
       begin
       counter_up<=0;
      end
     else if(up_en==1)
       begin
       counter_up<=counter_up+1;
      end
    end

     //counter_d_down
  always@(posedge clk)
    begin
     if(set)
       begin
       counter_down<=7'd127;
      end
     else if(down_en==1)
       begin
       counter_down<=counter_down-1;
      end
    end

//selectassign addrb=(down_en==1 )?counter_up :counter_down ;

//up_en delay
always@(posedge clk)
   begin
    if(set)
   begin
     rdata_ready<=0;
   end
  else
    begin
     rdata_ready<=rmem_rden;
    end
end
//mask_data
assign mask_data=(rdata_ready)?rmem_out:counter_k;

//counter_k_down
always@(posedge clk)
    begin
    if(set)
      begin
        counter_k<=7'b0;
      end
   else if(rdata_ready==1)
     begin
        counter_k<=rmem_out-1;
      end
   else
if(counter_k>1)
     begin
       counter_k<=counter_k-1;
     end
   end
   //rMEM use
rMEM MYrMEM (
.clka(clk), // input clka
.ena(ena), // input ena
.wea(wea), // input [0 : 0] wea
.addra(addra), // input [6 : 0] addra
.dina(dina), // input [6 : 0] dina
.clkb(clk), // input c // input [6 : 0] addra
.rstb(set), // input rstb
.enb(rmem_rden), // input enb
.addrb(addrb), // input [6 : 0] addrb
.doutb(rmem_out) // output [6 : 0] doutb
);


endmodule
rMEM存储前5个数据是 3、1、4、2 、3
仿真图如下:
Snap11.jpg
发表于 2013-5-24 22:30:33 | 显示全部楼层
最后结果用时钟采一下就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-4-25 08:11 , Processed in 0.031864 second(s), 9 queries , Gzip On, Redis On.

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