直方图统计模块——控制和地址生成模块1

    今天初步完成了直方图统计模块之控制和地址生成模块的仿真,从仿真波形来看基本符合预先的要求。整个模块的RTL图如下:

PLL模块输入27M像素时钟,输出108M时钟供其他模块使用,另外输出一路给niosII使用。wr_gen是WREN信号产生模块,WREN信号是片内RAM的读写控制信号。counter1模块是RAM读信号,负责读出RAM中存储的像素信息。counter2模块是RAM清零模块,负责对RAM内部单元清零。两个MUX是地址选择单元,此模块地址输出可能是像素值或两个counter模块的输出。

WREN模块代码如下:

 1 module wr_gen(clk,rst_n,start,cpurd,clearram,wren);
 2 
 3 input clk,rst_n,start,cpurd,clearram;
 4 output reg wren;
 5 
 6 reg [1:0]cont;
 7 always@(posedge clk/* or negedge rst_n*/)
 8 begin
 9     if(!start) //外部start信号,指示开始计数。必须由start控制,否则wren与外部27M像素时钟不同步。
10         cont<=0;
11     else
12     begin
13         if(cont==2'b11)
14             cont<=0;
15         else 
16             cont<=cont+1;
17     end 
18 end
19 always@(posedge clk /*or negedge rst_n*/)
20 begin
21     if(!rst_n)
22         wren<=0;
23     else 
24     begin
25         if(cpurd==1)
26             wren<=0;
27         else if(clearram==1)
28             wren<=1;
29         else if(cont==2'b10||cont==2'b11)
30             wren<=1;
31         else
32             wren<=0;
33     end
34 end
35 endmodule

顶层模块代码如下:

 1 module ctrl_addr(START,CLK27,PIXADDR,CPURD,CLRRAM,RST_N,PLL_RST, 
 2                         oWREN,oADDR,oDONE,oCLK108 );
 3 input START;
 4 input CLK27;
 5 input CPURD;
 6 input CLRRAM;
 7 input RST_N;
 8 input PLL_RST;
 9 input [7:0] PIXADDR;
10 output oWREN;
11 output reg oDONE;
12 output oCLK108;
13 output [7:0] oADDR;
14 
15 reg ostart;
16 wire clk0;
17 wire [7:0] q_addr1;
18 wire [7:0] q_addr2;
19 
20 //address generate
21 assign oADDR=(CPURD==1)? q_addr1:(CLRRAM==1?q_addr2:PIXADDR);
22 
23 //START信号必须与27MHz上升沿同步 、oDONE
24 always @ (posedge CLK27 or negedge RST_N)
25 begin
26     if(!RST_N)
27         begin
28         oDONE<=0;
29         ostart<=0;
30         end
31     else
32         begin
33         ostart<=START;//使START与27MHz时钟沿同步
34         oDONE<=!START;//完成信号,通知外部统计模块
35         end
36 end
37 pll1    pll1_inst (
38     .areset ( PLL_RST ),
39     .inclk0 ( CLK27 ),
40     .c0 ( clk0 ),     //内部108M
41     .c1 ( oCLK108 ),//输出108M接RAM 和nios
42     .locked ( )
43     );
44 //ram写信号产生模块
45 wr_gen u1 (
46     .clk(clk0),
47     .rst_n( RST_N ),
48     .start(ostart), //内部计数器开始计数
49     .cpurd(CPURD),  //读RAM数据
50     .clearram(CLRRAM),//读完后将RAM清零,以便统计下一帧
51     .wren(oWREN)
52 ) ;
53 //统计完成后的读地址产生
54 counter1    counter1_inst (
55     .aclr ( !RST_N ),
56     .clock ( !clk0 ),
57     .sset ( !CPURD ), //计数器重置
58     .q ( q_addr1 )
59     );
60 //统计完成后ram清零模块地址产生
61     counter2    counter2_inst (
62     .aclr ( !RST_N ),
63     .clock ( !clk0),
64     .sset ( !CLRRAM ),
65     .q ( q_addr2 )
66     );
67 
68 endmodule

Testbench代码:

 1 `timescale 1 ns/ 1 ps
 2 module ctrl_addr_vlg_tst();
 3 // constants                                           
 4 reg CLK27;
 5 reg CLRRAM;
 6 reg CPURD;
 7 reg [7:0] PIXADDR;
 8 reg PLL_RST;
 9 reg RST_N;
10 reg START;
11 // wires                                               
12 wire [7:0]  oADDR;
13 wire oCLK108;
14 wire oDONE;
15 wire oWREN;
16 
17 // assign statements (if any)                          
18 ctrl_addr i1 (
19 // port map - connection between master ports and signals/registers   
20     .CLK27(CLK27),
21     .CLRRAM(CLRRAM),
22     .CPURD(CPURD),
23     .PIXADDR(PIXADDR),
24     .PLL_RST(PLL_RST),
25     .RST_N(RST_N),
26     .START(START),
27     .oADDR(oADDR),
28     .oCLK108(oCLK108),
29     .oDONE(oDONE),
30     .oWREN(oWREN)
31 );
32 initial                                                
33 begin                                                  
34 CLK27=0;
35 CLRRAM=0;
36 CPURD=0;
37 PLL_RST=0;
38 RST_N=0;
39 START=0;
40 PIXADDR=0;
41 #250 RST_N=1;                                           
42 $display("Running testbench");                       
43 end 
44 
45 initial
46 begin:test
47 integer i;
48 # 277.8 START=1;
49 for(i=0;i<256;i=i+1)
50 begin
51     #37.04 PIXADDR=PIXADDR+1;//像素值作为地址
52 end
53 end
54  
55 initial
56 begin
57 # (277.8+37.04*80) START=0; //80个像素模拟一帧统计
58 # 9.26 CPURD=1;        //一帧统计结束后START=0,oDONE=1,CPURD有效
59 # (9.26*256) CPURD=0;CLRRAM=1; //读取结束,RAM清零
60 # (9.26*256) CLRRAM=0;
61 #  37.04 START=1;//新的一帧
62 end    
63 //27MHz                                               
64 always #(37.04/2) CLK27=!CLK27;                                                
65                                                    
66 endmodule

波形如下:

(1)总体图

START信号有效后,输出地址是像素值,wren信号周期性有效,开始统计并写入ram。start信号无效后,odone信号有效,通知外部模块,开始读取ram数值,cpurd模块有效表明开始读取。此时地址来自counter模块0~255递增。读取完成后cpurd信号无效,clrram信号有效,开始对ram清零。读取和清零两个阶段在下一帧开始统计之前结束。start信号开始,进行下一帧统计。

(2)前半部分放大

(3)中间部分

(4)后半部分

posted on 2012-11-12 17:00  万里-先生  阅读(256)  评论(0编辑  收藏  举报

导航