weixin_38293307
weixin_38293307
2017-10-31 14:10

急:基于FPGA的一位十进制计算器的verilog代码修改

30
  • fpga
  • verilog

下面是我下载的代码,采用FPGA的4*4键盘输入 。 我的板子是24M时钟,所以输入clk应该是24M吗?但是我仿真的时候col输出没有达到扫描的效果,不知道为什么?而且我想共阳极用四位数码管动态显示或者两位静态数码管显示,应该怎么改呢?大一生刚接触verilog,不是太懂,而且急用,望指教!谢谢!
module jisuanqi(clk, reset,row, col, seg_com, seg_data);
input clk;
input reset;
input [3:0] row;
output [3:0] col;
output [7:0] seg_data;
output [7:0] seg_com;

reg [7:0]outdata;
reg [7:0]datain[7:0];
reg [7:0]seg_com;
reg [7:0]seg_data;
reg [7:0]bcd_led;

reg [31:0] count1;

reg CLK_DIV;
reg [31:0]DCLK_DIV;
reg [7:0]key_temp;

reg [3:0] col;
reg [3:0] data; //按键值编码
reg [5:0] count;//delay_20ms
reg [2:0] state; //
reg key_flag; //
reg clk_500khz; //500KH
reg [3:0] col_reg; //
reg [3:0] row_reg; //

reg [7:0] buff,temp,mid;
reg [3:0] num1,num2;
reg [3:0] res;
reg [3:0] op,buff_reg;
reg [3:0] btemp;
reg flag_neg,eoc;
parameter add=4'b1010,sub=4'b1011,mult=4'b1100,div=4'b1101;
integer i;

always @(posedge clk or negedge reset)
if(!reset) begin clk_500khz<=0; count<=0; end
else
begin
if(count>=50) begin clk_500khz<=~clk_500khz;count<=0;end
else count<=count+1;
end
always @(posedge clk_500khz or negedge reset)
if(!reset) begin col<=4'b0000;state<=0;end
else
begin
case (state)
0:
begin
col[3:0]<=4'b0000;
key_flag<=1'b0;
if(row[3:0]!=4'b1111) begin state<=1;col[3:0]<=4'b1110;end //
else state<=0;
end
1:
begin
if(row[3:0]!=4'b1111) begin state<=5;end
else begin state<=2;col[3:0]<=4'b1101;end
end
2:
begin
if(row[3:0]!=4'b1111) begin state<=5;end //
else begin state<=3;col[3:0]<=4'b1011;end //
end
3:
begin
if(row[3:0]!=4'b1111) begin state<=5;end //
else begin state<=4;col[3:0]<=4'b0111;end //
end
4:
begin
if(row[3:0]!=4'b1111) begin state<=5;end //
else state<=0;
end
5:
begin
if(row[3:0]!=4'b1111)
begin
col_reg<=col; //
row_reg<=row; //
state<=5;
key_flag<=1'b1; //
end
else
begin state<=0;end
end
endcase
end

always @(clk_500khz or col_reg or row_reg)
begin
if(key_flag == 1'b1)
begin
case ({row_reg,col_reg})
8'b1110_1110:data<=4'b0000;//0
8'b1110_1101:data<=4'b0001;//1
8'b1110_1011:data<=4'b0010;//2
8'b1110_0111:data<=4'b0011;//3

         8'b1101_1110:data<=4'b0100;//4
         8'b1101_1101:data<=4'b0101;//5
         8'b1101_1011:data<=4'b0110;//6
         8'b1101_0111:data<=4'b0111;//7

         8'b1011_1110:data<=4'b1000;//8
         8'b1011_1101:data<=4'b1001;//9
         8'b1011_1011:data<=4'b1010;//10 '+'
         8'b1011_0111:data<=4'b1011;//11 '-'  

         8'b0111_1110:data<=4'b1100;//12 '*'
         8'b0111_1101:data<=4'b1101;//13 '/'
         8'b0111_1011:data<=4'b1110;//14 '='
         8'b0111_0111:data<=4'b1111;//15fuwei
        endcase 
    end 

end

//caculator part

always@(posedge clk)
begin
if(data == 4'b1111)
begin buff=0;op=0;eoc=0;num1=0;num2=0;temp=0;mid=0;end
else begin
if(data!=4'b1110)
begin
if((data>=4'b0000)&&(data<=4'b1001))
begin buff={4'b0000,data};end
else if((data>=4'b1010)&&(data<=4'b1110))
begin op=data;num1=buff[3:0];end
end
else
begin
if(eoc==0)
begin
num2=buff[3:0];
case(op)
add:
begin
buff=num1+num2;
/*if(buff>8'b00001001)
begin
mid=buff;
temp=8'b00000000;
for(i=1;i<=7;i=i+1)
begin
{temp,mid}={temp[6:0],mid,1'b0};
if(temp[3:0]>4'b0100)
begin temp[3:0]=temp[3:0]+4'b0011;end
if(temp[7:4]>4'b0100)
begin temp[7:4]=temp[7:4]+4'b0011;end
{buff_reg,res}={temp[6:0],buff[0]};
end
buff={buff_reg,res};
end*/
eoc=1;

end //add end
sub:
begin
/*if(num1>num2)
begin
buff_reg=num1+((~num2)+4'b0001);
buff={4'b0000,buff_reg};
flag_neg=1'b0;
end
else
begin
buff_reg=num2+((~num1)+4'b0001);
buff={4'b0000,buff_reg};
flag_neg=1'b1;
end
if(flag_neg==1)
buff[7:4]=4'b1111;*/
buff=num1-num2;
flag_neg=1'b0;
if(buff>200)
begin
buff=256-buff;
//buff[7:4]=4'b1111;
flag_neg=1'b1;
end

eoc=1;

end

            mult:
            begin
            buff=num1*num2;
            eoc=1;
            end

            div:
            begin
                if(num2==4'b0000) buff=0;
                else 
                begin
                buff_reg=num1;
                res=0;
                for(i=0;i<9;i=i+1)
                    begin
                    if(buff_reg>=num2)
                        begin
                        res=res+1;
                        buff_reg=buff_reg-num2;
                        end
                    else
                        buff={buff_reg,res};
                    end
                eoc=1;
                end
            end

            endcase         
            end
     end
     end

end

parameter CLK_FREQ = 'D50_000_000;//50MHZ
parameter DCLK_FREQ = 'D10;//AD_CLK 10/2HZ

always @(posedge clk)
if(DCLK_DIV < (CLK_FREQ / DCLK_FREQ)) // CLK_FREQ/DCLK_FREQ=5_000_000
DCLK_DIV <= DCLK_DIV+1'b1; // 10Hz
else
begin
DCLK_DIV <= 0;
CLK_DIV <= ~CLK_DIV; //5Hz
end

//display part
always @(negedge reset or negedge CLK_DIV )
begin
key_temp <= buff;
if(!reset)
begin
datain[0]<=8'b00000000;
datain[1]<=8'b00000000;
datain[2]<=8'b00000000;
datain[3]<=8'b00000000;
datain[4]<=8'b00000000;
datain[5]<=8'b00000000;
datain[6]<=8'b00000000;
datain[7]<=8'b00000000;
end
else
begin
datain[0]<=key_temp%10;
datain[1]<=key_temp/10%10;
datain[2]<=key_temp/100%10;
datain[3]<=key_temp/1000%10;

     end

end

always @(posedge clk)
begin
count1=count1+1; //32bit
end

always @(count1[14:12]) //scan LED *8, 50M/2^12=12k
begin
case(count1[14:12])
3'b000: begin
bcd_led = datain[0];
seg_com = 8'b00000001;
end
3'b001: begin
bcd_led=datain[1];
seg_com=8'b00000010;
end
3'b010: begin
bcd_led=datain[2];
seg_com=8'b00000100;
end
3'b011: begin
bcd_led=datain[3];
seg_com=8'b00001000;
end
3'b100: begin
bcd_led=datain[4];
seg_com=8'b00010000;
end
3'b101: begin
bcd_led=datain[5];
seg_com=8'b00100000;
end
3'b110: begin
bcd_led=datain[6];
seg_com=8'b01000000;
end
3'b111: begin
bcd_led=datain[7];
seg_com=8'b10000000;
end
endcase
end

always @(seg_com or bcd_led) //write code to LED
begin
case(bcd_led[3:0]) //display 0,1,2,.....9
4'h0:seg_data=8'hc0; //hgfedcba = 1100_0000
4'h1:seg_data=8'hf9; //hgfedcba = 1111_1001
4'h2:seg_data=8'ha4;
4'h3:seg_data=8'hb0;
4'h4:seg_data=8'h99;
4'h5:seg_data=8'h92;
4'h6:seg_data=8'h82;
4'h7:seg_data=8'hf8;
4'h8:seg_data=8'h80;
4'h9:seg_data=8'h90;
4'ha:seg_data=8'h88;
4'hb:seg_data=8'h83;
4'hc:seg_data=8'hc6;
4'hd:seg_data=8'ha1;
4'he:seg_data=8'h86;
4'hf:seg_data=8'h8e;
endcase

end

endmodule

  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

3条回答