集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 861|回复: 4

求帮助

[复制链接]
zxs1065264872 发表于 2014-4-26 19:39:47 | 显示全部楼层 |阅读模式
我正在学按键去抖,下面这个程序是按键按下时led亮,放手后,再次按下,led灭,我想要按键按下时led亮,放手时led灭,应该怎么做呢??程序是这个:                     module sw_debounce(
                    clk,rst_n,
                        sw1_n,sw2_n,sw3_n,
                           led_d1,led_d2,led_d3
                    );

input   clk;        //主时钟信号,50MHz
input   rst_n;        //复位信号,低有效
input   sw1_n,sw2_n,sw3_n;         //三个独立按键,低表示按下
output  led_d1,led_d2,led_d3;        //发光二极管,分别由按键控制

//---------------------------------------------------------------------------
reg[2:0] key_rst;  

always @(posedge clk  or negedge rst_n)
    if (!rst_n) key_rst <= 3'b111;
    else key_rst <= {sw3_n,sw2_n,sw1_n};

reg[2:0] key_rst_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @ ( posedge clk  or negedge rst_n )
    if (!rst_n) key_rst_r <= 3'b111;
    else key_rst_r <= key_rst;
   
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r & (~key_rst);
//---------------------------------------------------------------------------
reg[19:0]  cnt;        //计数寄存器

always @ (posedge clk  or negedge rst_n)
    if (!rst_n) cnt <= 20'd0;        //异步复位
        else if(key_an) cnt <=20'd0;
    else cnt <= cnt + 1'b1;
  
reg[2:0] low_sw;

always @(posedge clk  or negedge rst_n)
    if (!rst_n) low_sw <= 3'b111;
    else if (cnt == 20'hfffff)         //满20ms,将按键值锁存到寄存器low_sw中         cnt == 20'hfffff
      low_sw <= {sw3_n,sw2_n,sw1_n};
      
//---------------------------------------------------------------------------
reg  [2:0] low_sw_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @ ( posedge clk  or negedge rst_n )
    if (!rst_n) low_sw_r <= 3'b111;
    else low_sw_r <= low_sw;
//当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期
wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);

reg d1;
reg d2;
reg d3;
  
always @ (posedge clk or negedge rst_n)
    if (!rst_n) begin
        d1 <= 1'b0;
        d2 <= 1'b0;
        d3 <= 1'b0;
      end
    else begin                //某个按键值变化时,LED将做亮灭翻转
        if ( led_ctrl[0] ) d1 <= ~d1;       
        if ( led_ctrl[1] ) d2 <= ~d2;
        if ( led_ctrl[2] ) d3 <= ~d3;
      end

assign led_d3 = d1 ? 1'b1 : 1'b0;                //LED翻转输出
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;
  
endmodule
 楼主| zxs1065264872 发表于 2014-4-27 00:04:43 | 显示全部楼层
非常感谢!我自己才开始自学了一段时间,没有开发板,只能用上课的一点点时间用实验室的板子,我以后有问题可以向你请教吗??
 楼主| zxs1065264872 发表于 2014-5-9 20:32:05 | 显示全部楼层
你好,我在看一个乘法器的例子,有点不明白,这个是程序,module mux16(
                        clk,rst_n,
                        start,ain,bin,yout,done
                );
               
input clk;                //芯片的时钟信号。
input rst_n;        //低电平复位、清零信号。定义为0表示芯片复位;定义为1表示复位信号无效。
input start;         //芯片使能信号。定义为0表示信号无效;定义为1表示芯片读入输入管脚得乘数和被乘数,并将乘积复位清零。
input[15:0] ain;        //输入a(被乘数),其数据位宽为16bit.
input[15:0] bin;        //输入b(乘数),其数据位宽为16bit.
output[31:0] yout;        //乘积输出,其数据位宽为32bit.
output done;                //芯片输出标志信号。定义为1表示乘法运算完成.

reg[15:0] areg;        //乘数a寄存器
reg[15:0] breg;        //乘数b寄存器
reg[31:0] yout_r;        //乘积寄存器
reg done_r;
reg[4:0] i;                //移位次数寄存器


//------------------------------------------------
//数据位控制
always @(posedge clk or negedge rst_n)
        if(!rst_n) i <= 5'd0;
        else if(start && i < 5'd17) i <= i+1'b1;
        else if(!start) i <= 5'd0;

//------------------------------------------------
//乘法运算完成标志信号产生
always @(posedge clk or negedge rst_n)
        if(!rst_n) done_r <= 1'b0;
        else if(i == 5'd16) done_r <= 1'b1;                //乘法运算完成标志
        else if(i == 5'd17) done_r <= 1'b0;                //标志位撤销

assign done = done_r;

//------------------------------------------------
//专用寄存器进行移位累加运算
always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
                        areg <= 16'h0000;
                        breg <= 16'h0000;
                        yout_r <= 32'h00000000;
                end
        else if(start) begin                //启动运算
                        if(i == 5'd0) begin        //锁存乘数、被乘数
                                        areg <= ain;
                                        breg <= bin;
                                end
                        else if(i > 5'd0 && i < 5'd16) begin//i:1--16
                                        if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]};        //累加并移位
                                        else yout_r <= yout_r>>1;        //移位不累加
                                end
                        else if(i == 5'd16 && areg[15]) yout_r[31:16] <= yout_r[31:16]+breg;        //累加不移位
                end
end

assign yout = yout_r;

endmodule      ,对这个if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]};        //累加并移位    累加并移位的这一段不是很清楚,帮我一下,谢谢
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

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

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-5-7 05:18 , Processed in 0.059377 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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