@豆

为FPGA发狂的豆子

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
计算器
1 module calculator(
2 num,
3 num_decp,
4 num_dec,
5 num_sig,
6 cal,
7 enter,
8 result_int,
9 result_dec,
10 result_sig,
11 result_decp,
12 clk,
13 rst
14 );
15
16  input clk;
17 input rst;
18 input [9:0] num;
19 input num_decp;
20 input num_sig;
21 input [9:0] num_dec;
22 input [3:0] cal;
23 input enter;
24 output [19:0] result_int;
25 output [9:0] result_dec;
26 output result_sig;
27 output result_decp;
28
29 reg [9:0] num1;
30 reg num1_decp;
31 reg num1_sig;
32 reg [9:0] num1_dec;
33 reg [9:0] num2;
34 reg num2_decp;
35 reg num2_sig;
36 reg [9:0] num2_dec;
37 reg [9:0] num1cal;
38 reg num1cal_decp;
39 reg num1cal_sig;
40 reg [9:0] num1cal_dec;
41 reg [9:0] num2cal;
42 reg num2cal_decp;
43 reg num2cal_sig;
44 reg [9:0] num2cal_dec;
45 reg [3:0] cal_tmp;
46 reg [19:0] result_int;
47 reg [9:0] result_dec;
48 reg result_sig;
49 reg result_decp;
50 reg [3:0] cal_st;
51
52 always@(posedge clk or negedge rst)
53 begin
54 if(~rst)
55 begin
56 cal_tmp<=4'b0000;
57 num1<=0;
58 num2<=0;
59 num1_decp<=0;
60 num2_decp<=0;
61 num1_dec<=0;
62 num2_dec<=0;
63 num1_sig<=0;
64 num2_sig<=0;
65 num1cal<=0;
66 num2cal<=0;
67 num1cal_decp<=0;
68 num2cal_decp<=0;
69 num1cal_dec<=0;
70 num2cal_dec<=0;
71 num1cal_sig<=0;
72 num2cal_sig<=0;
73 result_int<=0;
74 result_dec<=0;
75 result_decp<=0;
76 result_sig<=0;
77 cal_st<=0;
78 end
79 else
80 begin
81 if(|cal)
82 begin
83 num1_sig<=num_sig;
84 num1<=num;
85 num1_decp<=num_decp;
86 num1_dec<=num_dec;
87 cal_tmp<=cal;
88 end
89 else
90 begin
91 if(enter)
92 begin
93 num2_sig<=num_sig;
94 num2<=num;
95 num2_decp<=num_decp;
96 num2_dec<=num_dec;
97 case({num1_sig,num2_sig,cal_tmp})
98 6'b000001://num1+num2
99 begin
100 cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
101 num1cal_sig<=num1_sig;
102 num1cal<=num1;
103 num1cal_decp<=num1_decp;
104 num1cal_dec<=num1_dec;
105 num2cal_sig<=num2_sig;
106 num2cal<=num2;
107 num2cal_decp<=num2_decp;
108 num2cal_dec<=num2_dec;
109 end
110 6'b010001://num1+(-num2)=num1-num2
111 begin
112 cal_st<=2;//num1-num2,num1_sig=num2_sig=0
113 num1cal_sig<=num1_sig;
114 num1cal<=num1;
115 num1cal_decp<=num1_decp;
116 num1cal_dec<=num1_dec;
117 num2cal_sig<=0;
118 num2cal<=num2;
119 num2cal_decp<=num2_decp;
120 num2cal_dec<=num2_dec;
121 end
122 6'b100001://-num1+num2
123 begin
124 cal_st<=2;
125 //alternate num1 and num2, then it's still num1-num2
126 num1cal_sig<=0;
127 num1cal<=num2;
128 num1cal_decp<=num2_decp;
129 num1cal_dec<=num2_dec;
130 num2cal_sig<=0;
131 num2cal<=num1;
132 num2cal_decp<=num1_decp;
133 num2cal_dec<=num1_dec;
134 end
135 6'b110001://-num1+(-num2)
136 begin
137 cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
138 num1cal_sig<=num1_sig;
139 num1cal<=num1;
140 num1cal_decp<=num1_decp;
141 num1cal_dec<=num1_dec;
142 num2cal_sig<=num2_sig;
143 num2cal<=num2;
144 num2cal_decp<=num2_decp;
145 num2cal_dec<=num2_dec;
146 end
147 6'b000010://num1-num2
148 begin
149 cal_st<=2;//num1-num2,num1_sig=num2_sig=0
150 num1cal_sig<=num1_sig;
151 num1cal<=num1;
152 num1cal_decp<=num1_decp;
153 num1cal_dec<=num1_dec;
154 num2cal_sig<=num2_sig;
155 num2cal<=num2;
156 num2cal_decp<=num2_decp;
157 num2cal_dec<=num2_dec;
158 end
159 6'b010010://num1-(-num2)
160 begin
161 cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
162 num1cal_sig<=0;
163 num1cal<=num1;
164 num1cal_decp<=num1_decp;
165 num1cal_dec<=num1_dec;
166 num2cal_sig<=0;
167 num2cal<=num2;
168 num2cal_decp<=num2_decp;
169 num2cal_dec<=num2_dec;
170 end
171 6'b100010://-num1-num2
172 begin
173 cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
174 num1cal_sig<=num1_sig;
175 num1cal<=num1;
176 num1cal_decp<=num1_decp;
177 num1cal_dec<=num1_dec;
178 num2cal_sig<=1;
179 num2cal<=num2;
180 num2cal_decp<=num2_decp;
181 num2cal_dec<=num2_dec;
182 end
183 6'b110010://-num1-(-num2)=num2-num1
184 begin
185 cal_st<=2;//num1-num2,num1_sig=num2_sig=0
186 num1cal_sig<=0;
187 num1cal<=num2;
188 num1cal_decp<=num2_decp;
189 num1cal_dec<=num2_dec;
190 num2cal_sig<=0;
191 num2cal<=num1;
192 num2cal_decp<=num1_decp;
193 num2cal_dec<=num1_dec;
194 end
195 6'b000100://num1*num2,result_sig=num1_sig^num2_sig
196 begin
197 cal_st<=3;
198 num1cal_sig<=num1_sig;
199 num1cal<=num1;
200 num1cal_decp<=num1_decp;
201 num1cal_dec<=num1_dec;
202 num2cal_sig<=num2_sig;
203 num2cal<=num2;
204 num2cal_decp<=num2_decp;
205 num2cal_dec<=num2_dec;
206 end
207 6'b010100://num1*(-num2)
208 begin
209 cal_st<=3;
210 num1cal_sig<=num1_sig;
211 num1cal<=num1;
212 num1cal_decp<=num1_decp;
213 num1cal_dec<=num1_dec;
214 num2cal_sig<=num2_sig;
215 num2cal<=num2;
216 num2cal_decp<=num2_decp;
217 num2cal_dec<=num2_dec;
218 end
219 6'b100100://(-num1)*num2
220 begin
221 cal_st<=3;
222 num1cal_sig<=num1_sig;
223 num1cal<=num1;
224 num1cal_decp<=num1_decp;
225 num1cal_dec<=num1_dec;
226 num2cal_sig<=num2_sig;
227 num2cal<=num2;
228 num2cal_decp<=num2_decp;
229 num2cal_dec<=num2_dec;
230 end
231 6'b110100://(-num1)*(-num2)
232 begin
233 cal_st<=3;
234 num1cal_sig<=num1_sig;
235 num1cal<=num1;
236 num1cal_decp<=num1_decp;
237 num1cal_dec<=num1_dec;
238 num2cal_sig<=num2_sig;
239 num2cal<=num2;
240 num2cal_decp<=num2_decp;
241 num2cal_dec<=num2_dec;
242 end
243 6'b001000://num1/num2
244 begin
245 cal_st<=4;
246 num1cal_sig<=num1_sig;
247 num1cal<=num1;
248 num1cal_decp<=num1_decp;
249 num1cal_dec<=num1_dec;
250 num2cal_sig<=num2_sig;
251 num2cal<=num2;
252 num2cal_decp<=num2_decp;
253 num2cal_dec<=num2_dec;
254 end
255 6'b011000://num1/(-num2)
256 begin
257 cal_st<=4;
258 num1cal_sig<=num1_sig;
259 num1cal<=num1;
260 num1cal_decp<=num1_decp;
261 num1cal_dec<=num1_dec;
262 num2cal_sig<=num2_sig;
263 num2cal<=num2;
264 num2cal_decp<=num2_decp;
265 num2cal_dec<=num2_dec;
266 end
267 6'b101000://(-num1)/num2
268 begin
269 cal_st<=4;
270 num1cal_sig<=num1_sig;
271 num1cal<=num1;
272 num1cal_decp<=num1_decp;
273 num1cal_dec<=num1_dec;
274 num2cal_sig<=num2_sig;
275 num2cal<=num2;
276 num2cal_decp<=num2_decp;
277 num2cal_dec<=num2_dec;
278 end
279 6'b111000://(-num1)/(-num2)
280 begin
281 cal_st<=4;
282 num1cal_sig<=num1_sig;
283 num1cal<=num1;
284 num1cal_decp<=num1_decp;
285 num1cal_dec<=num1_dec;
286 num2cal_sig<=num2_sig;
287 num2cal<=num2;
288 num2cal_decp<=num2_decp;
289 num2cal_dec<=num2_dec;
290 end
291 endcase
292
293
294 case(cal_st)
295 4'd1://num1cal+num2cal,result_sig=num1cal_sig&num2cal_sig,where num1cal_sig=num2cal_sig
296 begin
297 result_sig<=num1cal_sig&num2cal_sig;
298 result_int<=num1cal+num2cal+(num1cal_dec+num2cal_dec)/1000;
299 result_decp<=num1cal_decp|num2cal_decp;
300 result_dec<=(num1cal_dec+num2cal_dec)%1000;
301 end
302 4'd2://num1cal-num2cal,num1cal_sig=num2cal_sig=0
303 begin
304 if(num1cal<num2cal)//-(num2cal-num1cal)
305 begin
306 result_sig<=1;
307 if(num2cal_dec<num1cal_dec)
308 begin
309 result_int<=num2cal-num1cal-1;
310 result_decp<=1;
311 result_dec<=1000+num2cal_dec-num1cal_dec;
312 end
313 else
314 begin
315 result_int<=num2cal-num1cal;
316 result_decp<=num1cal_decp|num2cal_decp;
317 result_dec<=num2cal_dec-num1cal_dec;
318 end
319 end
320 else//num1cal>=num2cal
321 begin
322 if(num1cal>num2cal)
323 begin
324 result_sig<=0;
325 if(num1cal_dec<num2cal_dec)
326 begin
327 result_int<=num1cal-num2cal-1;
328 result_decp<=1;
329 result_dec<=1000+num1cal_dec-num2cal_dec;
330 end
331 else//num1cal_dec>=num2cal_dec
332 begin
333 result_int<=num1cal-num2cal;
334 result_decp<=num1cal_decp|num2cal_decp;
335 result_dec<=num1cal_dec-num2cal_dec;
336 end
337 end
338 else//num1cal==num2cal
339 begin
340 if(num1cal_dec<num2cal_dec)//num1cal.dec1-num2cal.dec2=-(num2cal.dec2-num1cal.dec1)
341 begin
342 result_sig<=1;
343 result_int<=num2cal-num1cal;
344 result_decp<=1;
345 result_dec<=num2cal_dec-num1cal_dec;
346 end
347 else//num1cal.dec>=num2cal.dec
348 begin
349 result_sig<=0;
350 result_int<=num1cal-num2cal;
351 result_decp<=num1cal_decp|num2cal_decp;
352 result_dec<=num1cal_dec-num2cal_dec;
353 end
354 end
355 end
356 end
357 4'd3:
358 begin
359 result_sig<=num1cal_sig^num2cal_sig;
360 result_int<=num1cal*num2cal+(num1cal*num2cal_dec)/1000+(num2cal*num1cal_dec)/1000+(num1cal_dec*num2cal_dec)/1000000;
361 result_decp<=num1cal_decp|num2cal_decp;
362 result_dec<=((num1cal_dec*num2cal_dec)%1000000)/1000+(num1cal*num2cal_dec)%1000+(num2cal*num1cal_dec)%1000;
363 end
364 4'd4://num1cal/num2cal
365 begin
366 result_sig<=num1cal_sig^num2cal_sig;
367 result_int<=(num1cal*1000+num1cal_dec)/(num2cal*1000+num2cal_dec);
368 result_dec<= (((num1cal*1000+num1cal_dec)%(num2cal*1000+num2cal_dec))*1000/(num2cal*1000+num2cal_dec));
369 if(result_dec==0)
370 begin
371 result_decp<=0;
372 end
373 else
374 begin
375 result_decp<=1;
376 end
377 end
378 endcase
379 end
380 end
381 end
382 end
383
384 endmodule
385

 

前两天看到网上有人问关于verilog编写计算器的问题,就突然想做一个试试,本来以为很简单,结果发现有太多的状态需要考虑。程序里用的方法比较笨,if套if,case接case的,不过到目前还没有发现哪里有错误。

工程的输入num为输入数字的整数部分,num_decp为小数点,num_dec为小数部分,num_sig为正负符号,cal为计算符,enter相当于计算器上的等号,result_int为结果的整数部分,result_dec为小数部分,result_sig为符号,result_decp为小数点,clk为驱动时钟,rst为清零按键。

一般使用计算器的顺序是先输入第一个数,然后按加减乘除等计算符,之后就输入第二个数,最后按等号出答案。所以前后两个数为穿行输入,只需要一个数字输入端口,即num,num_decp,num_dec,num_sig。当检测到四位cal中的任何一位为1时,就可知道当前输入的计算符为加减乘除的哪一个,此时将数字输入端口的值传到第一个数num1,将cal传到cal_tmp;当检测到enter为1时,将数字输入端口的值传到第二个数num2,此时可由两个数的符号和cal的值将计算情况分为四个状态,如97-291行所示。此时根据状态将num1和num2的值传给计算单元num1cal和num2cal,在294-378行中进行计算。

做的很粗糙,输入的整数范围只有-1023~1023,小数只有三位。各位有兴趣可继续扩展。

posted on 2010-09-10 17:58  @豆  阅读(5030)  评论(0编辑  收藏  举报