集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1238|回复: 1

verilog编程问题

[复制链接]
chenhebing 发表于 2012-9-19 15:04:35 | 显示全部楼层 |阅读模式
小弟刚学FPGA,最近看了一个16位的乘法器,例程中只给了我核心处理器模块,我想把按键和数码管显示全部做上去,可是出了问题,好几天了不知道怎么解决。代码如下,请大神指点。

module mux16(clk,rst_n,done,dig,seg,keyin,keyout);
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:h0] yout;        //乘积输出,其数据位宽为32bit.
input [3:0] keyin;
output [2:0] keyout;
output done;                //芯片输出标志信号。定义为1表示乘法运算完成.
output [7:0] dig;
output [7:0] seg;

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


//reg [3:0]  keyval;

//reg [3:0] start_r;
//reg [3:0] point_r;

wire [3:0] keyval;
wire [31:0] yout;
wire int_r;

assign done = done_r;
assign yout = yout_rr;

key        key_u1(.clk(clk),.rst(rst_n),.int_r(int_r),.keyval(keyval),.keyin(keyin),.keyout(keyout));

dyn_seg seg_u1(.clk(clk),.d(yout),.dig(dig),.seg(seg));

always @ (posedge clk or negedge rst_n)
begin
        if(!rst_n)
        begin
                ain <= 16'd0;
                bin <= 16'd0;
                point <=1'b0;
        end
        else
        case(keyval)
                4'd10:
                begin
                        point <=1'b1;
        //                bin <=16'd0;
                        start <=1'b0;
                end
                4'd11:
                begin
                        start <=1'b1;
                end
                default:
                begin
                        if(int_r)
                        begin
                        if(!point)
                                ain <= {ain[11:0],keyval};
                        else
                                bin <= {bin[11:0],keyval};
                        end
                end
        endcase
end


always @ (posedge clk)
begin
        if(start)
                yout_rr <=yout_r;
        else
                if(!point)
                        yout_rr <=ain;
                else
                        yout_rr <=bin;
end

//数据位控制
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;                //标志位撤销

//专用寄存器进行移位累加运算
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
                                        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

endmodule

module key(clk,rst,int_r,keyval,keyin,keyout);       
input  clk;                                                //系统时钟
input  rst;                                                        //同步复位       
output int_r;       
input         [3:0] keyin;                                //键盘接口输入
output [2:0] keyout;                                //键盘接口输出
output [3:0] keyval;                                //按键值

reg        [3:0]        keyval_r;
reg        [2:0]        keyout_r;
reg        [3:0]        dout1,dout2,dout3;                        //寄存
reg        [11:0] keytmp1;
reg         [11:0] keytmp2;
reg        [17:0] clk_count;
reg        [1:0]        cnt4;
reg int_rr;

wire        [11:0] nFlag;
wire        clk_en;
wire        clk4_en;
wire        [3:0]        key_done;                                //按键消抖输出

parameter  cmp_cnt = 100000;                         //消抖时钟分频系数=0.002*系统时钟频率

assign keyval=keyval_r;
assign keyout=keyout_r;

/*产生消抖时钟使能信号*/

always @ (posedge clk)                                               
begin
        if(!rst)
                clk_count <= 0;
        else
                if(clk_en)
                        clk_count <= 0;
                else
                        clk_count <= clk_count + 1'b1;
end

assign clk_en = (clk_count == cmp_cnt);        //Clock=50MHz时,ClkEN=2ms

/*产生键盘时钟使能信号*/
always @ (posedge clk)
begin
        if(!rst)
                cnt4 <= 2'd0;
        else
                if(clk_en)
                begin
                        if(clk4_en)
                                cnt4 <= 2'd0;
                        else
                                cnt4 <= cnt4 + 1'b1;
                end
end
assign clk4_en = (cnt4 == 2'b11) && clk_en;        //Clk4En=4*ClkEn

/*键盘消抖模块*/       
assign key_done = (dout1 | dout2 | dout3);       

always @ (posedge clk)
begin
        if(clk_en)                                                //消抖时钟使能信号
        begin
                dout1 <= keyin;
                dout2 <= dout1;
                dout3 <= dout2;
        end       
end


/*输出键盘行扫描信号*/
always @ (posedge clk)
begin
        if(!rst)
                keyout_r <= 3'b110;
        else if(clk4_en)
        begin
                if(keyout_r == 3'b011)
                        keyout_r <= 3'b110;
                else
                        keyout_r <= {keyout_r[1:0],1'b1};
        end       
end


/*读取键盘状态值*/
always @ (posedge clk)
begin
        if(!rst)
                keytmp1 <= 12'hfff;
        else
                if(clk4_en)
                begin
                        case(keyout_r)
                                3'b110 : keytmp1[3:0] <= key_done;         
                                3'b101 : keytmp1[7:4] <= key_done;       
                                3'b011 : keytmp1[11:8] <= key_done;               
                                default : keytmp1 <= 12'hfff;
                        endcase
                end
end

always @ (posedge clk)
begin
        keytmp2 <= keytmp1;       
end

assign nFlag = ~keytmp1 & keytmp2;
assign int_r =int_rr;
//assign int_r = nFlag;
always @ (posedge clk)
begin
        if(nFlag)
                int_rr <=1'b1;
        else
                int_rr <=1'b0;
end

/*输出键盘值*/
always @ (posedge clk)
begin
        if(!rst)
                keyval_r <= 4'd0;
        else
        begin
                if(nFlag[0])                        keyval_r <= 4'd1;
                else if(nFlag[1])                keyval_r <= 4'd4;
                else if(nFlag[2])                keyval_r <= 4'd7;
                else if(nFlag[3])                keyval_r <= 4'd10;
                else if(nFlag[4])                keyval_r <= 4'd2;
                else if(nFlag[5])                keyval_r <= 4'd5;
                else if(nFlag[6])                keyval_r <= 4'd8;
                else if(nFlag[7])                keyval_r <= 4'd0;
                else if(nFlag[8])         keyval_r <= 4'd3;
                else if(nFlag[9])                keyval_r <= 4'd6;
                else if(nFlag[10])        keyval_r <= 4'd9;
                else if(nFlag[11])        keyval_r <= 4'd11;
        end
end

endmodule


module dyn_seg(clk,d,dig,seg);
input clk;
input [31:0] d;
output [7:0] dig;
output [7:0] seg;

reg [16:0] clk_time;
reg [7:0] dig_r;
reg [7:0] seg_r;
reg [2:0] count;
reg [3:0] disp_dat;

assign dig=dig_r;
assign seg=seg_r;

always @ (posedge clk)
begin
        clk_time <= clk_time+1'b1;
        if(clk_time==17'd99999)
        begin
                count <= count+1'b1;
                clk_time <= 17'd0;
        end
end

always @ (posedge clk)
begin
        case(count)
                3'd0:        disp_dat=d[31:28];
                3'd1:        disp_dat=d[27:24];
                3'd2:        disp_dat=d[23:20];
                3'd3:        disp_dat=d[19:16];
                3'd4:        disp_dat=d[15:12];
                3'd5:        disp_dat=d[11:8];
                3'd6:        disp_dat=d[7:4];
                3'd7:        disp_dat=d[3:0];
        endcase
       
        case(count)
                3'd0:        dig_r=8'b01111111;
                3'd1:        dig_r=8'b10111111;
                3'd2:        dig_r=8'b11011111;
                3'd3:        dig_r=8'b11101111;
                3'd4:        dig_r=8'b11110111;
                3'd5:        dig_r=8'b11111011;
                3'd6:        dig_r=8'b11111101;
                3'd7:        dig_r=8'b11111110;
        endcase
end


always @ (disp_dat)
        begin
                case(disp_dat)
                        4'h0:        seg_r=8'h3f;
                        4'h1:        seg_r=8'h06;
                        4'h2:        seg_r=8'h5b;
                        4'h3:        seg_r=8'h4f;
                        4'h4:        seg_r=8'h66;
                        4'h5:        seg_r=8'h6d;
                        4'h6:        seg_r=8'h7d;
                        4'h7:        seg_r=8'h07;
                        4'h8:        seg_r=8'h7f;
                        4'h9:        seg_r=8'h6f;
                        4'ha:        seg_r=8'h77;
                        4'hb:        seg_r=8'h7c;
                        4'hc:        seg_r=8'h39;
                        4'hd: seg_r=8'h5e;
                        4'he:        seg_r=8'h79;
                        4'hf:        seg_r=8'h71;
                endcase
        end
endmodule
 楼主| chenhebing 发表于 2012-9-19 15:06:25 | 显示全部楼层
4X3为12,但是3X4就成了8,不知道为什么,找不到出错的原因,求指点。谢谢了!
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

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

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-5-18 08:31 , Processed in 0.074869 second(s), 24 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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