Thông báo

Collapse
No announcement yet.

Mong các bác coi giúp em đoạn code!

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Mong các bác coi giúp em đoạn code!

    Em viết 1 mini calculator, thực hiện các phép + _ * / . Tất cả chạy ổn định rồi. Em viết thêm phím nhớ M+,MR để gọi số nhớ, MC xóa số nhớ. Em dung biến mem[n:0] để lưu kết quả phép tính, khi nhấn MR thì xuất ra LCD. Nghĩ đơn giản nhưng khi viết lại ko chạy được. ĐÂy chỉ là module xử lý chính, em còn các module quét phím, chuyển binary sang BCD để hiện thị LCD nữa. 2 state em dùng cho phím nhớ là hienthi_state và phímnhớ_state. Em viết theo lưu đồ máy trạng thái. Các anh xem góp y cho em với ạ,
    Nếu em thay phim C = phím DEL tức là xóa từng kí tự, có vẻ công việc sẽ phức tạp vì giá trị nhập trong input_state sẽ đc nhân 10+ giá trị mới nhập, vậy nếu ta xóa 1 số sẽ chia 10 lấy phần nguyên, nhưng việc đó làm thế nào xin các anh chị góp ý.
    Code:
    module maincontrol(clock, data_ready, scan_code,lcd_out, lcd_rs,lcd_en,lcd_rw);
    parameter n=44;
    parameter n_div =61;
    parameter int_digit=8;
    parameter fract_digit=5;
    parameter digit=13;
    input clock;
    input data_ready;
    input [7:0] scan_code;
    output  [7:0] lcd_out;
    output  lcd_rs;
    output  lcd_en;
    output reg lcd_rw;
    parameter lcd_start_state =5'b 00000;
    parameter lcd_set_state   =5'b 00001;
    parameter AC_state        =5'b 00010;
    parameter C_state         =5'b 00011;
    parameter input_state     =5'b 00100;
    parameter two_opr_state   =5'b 00101;
    parameter two_opr1_state  =5'b 00110;
    parameter wait_state      =5'b 00111;
    parameter scancode_state  =5'b 01000;
    parameter div_S0_state    =5'b 10110;
    parameter div_S1_state    =5'b 10111;
    parameter div_S2_state    =5'b 11000;
    parameter div_S3_state    =5'b 11001;
    parameter to_uniform_state=5'b 11010;
    parameter lcd_wait_state  =5'b 11011;
    parameter lcd_wait1_state =5'b 11100;
    parameter phimnho_state   =5'b 11101;
    parameter hienthi_state   =5'b 11110;
    reg [4:0] state;
    //----------------------------------ma phim nhan
    // hang 1
    parameter zero_sc       =8'b 11011110;	//  so 0
    parameter point_sc      =8'b 11101110;	//  dau .
    parameter equal_sc      =8'b 10111110;	//  dau =
    parameter AC_sc         =8'b 01111110;	// 	phim AC/C
    // hang 2
    parameter seven_sc      =8'b 11101101;    //  so 7
    parameter eight_sc      =8'b 11011101;	//  so 8
    parameter mc_sc       =8'b 10111101;	//	so 9
    parameter madd_sc      =8'b 01111101;	//	phim shift
    // hang 3
    parameter four_sc       =8'b 11101011;	// 	so 4
    parameter five_sc       =8'b 11011011;	// 	so 5
    parameter six_sc        =8'b 10111011;	//	so 6
    parameter mr_sc        =8'b 01111011;	//	dau x/:
    // hang 4
    parameter one_sc        =8'b 11100111;	// 	so 1 
    parameter two_sc        =8'b 11010111;	//	so 2
    parameter three_sc      =8'b 10110111;   // 	so 3
    parameter add_sc        =8'b 01110111;	//	dau +/-
    // khai bao phep tinh hai toan hang
    parameter non_op  =4'b  0000;
    parameter add     =4'b  0001;
    parameter sub     =4'b  0010; 
    parameter div     =4'b  0011;
    parameter mul     =4'b  0100;
    reg			 		shift_flag;			// bao cho biet tinh arc
    reg	[3:0]	 		number_value;
    reg [n:0]	 		input_value;
    reg [n:0]	 		result_value;
    reg	[n+1:0]	 		return_add;
    reg	[n+1:0]	 		mem;
    reg 		 		equal,mad;
    reg	[3:0]	 		cur_op;
    reg	[3:0]	 		next_op;
    reg					point_flag;
    reg	[2*n:0]	 		return_mul;
    // dem digit
    reg [4:0]	 		int_cnt;				// truoc dau .
    reg	[4:0]	 		fract_cnt;			// sau dau .
    // bo chia
    reg	[n_div:0]		div1_s;
    reg	[n:0]	 		div2_s;
    reg	[n_div:0]		quotient;			// ket qua
    reg	[n+n_div-2:0]	divider;			// so chia
    reg	[n_div-1:0]		dividend;			// so bi chia
    reg [5:0]			div_cnt;
    // khai bao cho lcd
    reg [2:0]			lcd_sel_s;
    reg	[7:0]			lcd_val_s;
    reg	[n:0]			lcd_result_s;		// ket qua hiet thi lcd
    reg					lcd_start_s;		// ban dau phai cho la 1
    wire				lcd_ready_s;	
    reg					lcd_clear_flag;
    reg					sc_return_flag;		// sau khi xoa lcd thi tra ve trang thai scancode
    wire				lcd_err_s;
    reg [n:0] tam;
    reg [4:0] dem;
    // ham nhan10  61bit
    function [n_div:0] mul_10_ext;
    input [n_div:0] l;
    reg [n_div-1:0] l_3;		// nhan 2^3;
    reg [n_div-1:0] l_1;		// nhan 2^1;
    reg [n_div:0] result;
    begin
    	l_3={l[n_div-4:0],3'b 000};
    	l_1={l[n_div-2:0],1'b 0};
    	result[n_div]= l[n_div];
    	result[n_div-1:0]=l_3+l_1;
    	mul_10_ext=result;
    end
    endfunction
    // ham nhan 10
    function [n:0] mul_10;
    input [n:0] l;
    reg [n-1:0] l_3;		// nhan 2^3;
    reg [n-1:0] l_1;		// nhan 2^1;
    reg [n:0] result;
    begin
    	l_3={l[n-4:0],3'b 000};
    	l_1={l[n-2:0],1'b 0};
    	result[n]= l[n];
    	result[n-1:0]=l_3+l_1;
    	mul_10=result;
    end
    endfunction
    // ham cong_tru
    function [n+1:0] add_sub;
    input sign_l;
    input sign_r;
    input [n-1:0] l;
    input [n-1:0] r;
    reg [n+1:0] result;
    begin
    if((sign_l^sign_r)==1)					// khac dau
    	begin
    	if(l>=r)
    		begin
    		result[n+1]=sign_l;			// l>r dau cua ket qua giong dau cua l
    		result[n:0]= ({1'b0,l})-({1'b 0,r});
    		end
    	else
    		begin
    		result[n+1]=sign_r;			
    		result[n:0]= ({1'b0,r})-({1'b 0,l});
    		end
    	end
    else								// cung dau
    	begin
    	result[n+1]=sign_l;			
    	result[n:0]= ({1'b0,l})+({1'b 0,r});
    	end
    add_sub=result;
    end
    endfunction
    // ham nhan 
    function [2*n:0] multiplier;
    input  [n:0] l,r;
    reg [2*n:0] result;
    begin
    result[2*n]=(l[n]^r[n]);
    result[2*n-1:0]=l[n-1:0]*r[n-1:0];
    multiplier=result;
    end
    endfunction
    lcd_modul z(clock,lcd_sel_s,lcd_start_s,lcd_val_s,lcd_result_s,lcd_ready_s,lcd_en,lcd_err_s,lcd_rs,lcd_out);
    always @(posedge clock)
    begin
    lcd_rw=0;
    mem=0;
    case (state)
    lcd_start_state:	begin		
    					lcd_start_s=1;
    					state=lcd_set_state;
    					end 
    lcd_set_state:	begin				
    				lcd_sel_s = 3'b 000;					// set func cho lcd
    				if(lcd_ready_s==1)
    					begin
    					lcd_start_s=0;
    					state=AC_state;
    					end
    				end
    lcd_wait_state:	begin										// cho lcd_ready xuong muc thap
    				if (lcd_ready_s==0)
    				state=lcd_wait1_state;
    				end
    lcd_wait1_state:begin									// cho lcd_ready len muc 1
    				if (lcd_ready_s==1)
    					begin					
    						lcd_start_s=0;
    						if (sc_return_flag==1)				// xoa hien thi roi tra ve trang thai nhap
    							begin
    							state=scancode_state;							// vi khi co phim an moi xoa ket qua
    							sc_return_flag=0;				// dang nhap ky tu nay nen phai tra ve trang thai scancode
    							end
    						else
    						state=wait_state;				// cho nhap ky tu moi
    						end
    					end				
    AC_state:		begin
    				int_cnt=0;
    				fract_cnt=0;
    				result_value=0;
    				input_value=0;
    				lcd_result_s=0;
    				next_op=non_op;
    				cur_op=non_op;
    				point_flag=0;
    				lcd_start_s=1;
    				lcd_sel_s=3'b 001;			// clear lcd
    				shift_flag=0;
    				lcd_clear_flag=0;
    				equal=0;
    				state=lcd_wait_state;
    				end
    C_state:		begin
    				int_cnt=0;
    				fract_cnt=0;
    				shift_flag=0;
    				input_value=0;
    				point_flag=0;
    				lcd_start_s=1;
    				lcd_sel_s=3'b 001;			// clear lcd
    				state=lcd_wait_state;
    				end
    scancode_state:	begin
    				if(lcd_err_s==1)
    					begin
    					if(scan_code==AC_sc)
    						state=AC_state;
    					end
    				else
    					begin
    					if(data_ready==1)
    						begin
    						if(lcd_clear_flag==1)			// xoa hien thi chuan bi nhap moi
    							begin
    							if(scan_code==add_sc)
    								lcd_clear_flag=0;
    							else
    								begin
    								lcd_clear_flag=0;		// khi an phim moi xoa ket qua cu
    								lcd_start_s=1;
    								lcd_sel_s=3'b 001;
    								sc_return_flag=1;
    								state=lcd_wait_state;
    								end
    							end
    						else
    							begin
    							case (scan_code)
    								AC_sc	: 		begin
    												if(shift_flag==0)	
    												state=AC_state;
    												else
    												state=C_state;				//phim C
    												end
    								zero_sc	:		begin
    												number_value=4'b 0000;
    												state=input_state;
    												end
    								one_sc	:		begin
    												number_value=4'b 0001;
    												state=input_state;
    												end
    								two_sc	:		begin
    												number_value=4'b 0010;
    												state=input_state;
    												end
    								three_sc:		begin
    												number_value=4'b 0011;
    												state=input_state;
    												end
    								four_sc	:		begin
    												number_value=4'b 0100;
    												state=input_state;
    												end
    								five_sc	:		begin
    												number_value=4'b 0101;
    												state=input_state;
    												end
    								six_sc	:		begin
    												number_value=4'b 0110;
    												state=input_state;
    												end
    								seven_sc:		begin
    												number_value=4'b 0111;
    												state=input_state;
    												end
    								eight_sc:		begin
    												number_value=4'b 1000;
    												state=input_state;
    												end
    					/*			nine_sc	:		begin
    												number_value=4'b 1001;
    												state=input_state;
    												end */
    								madd_sc	:		begin
    												state=phimnho_state;
    												end
    								mr_sc	:		begin
    												state=hienthi_state;
    												end	
    								mc_sc	:       begin
    												mem=0;
    												state=lcd_wait_state;
    												end																						
    								add_sc	:		begin								// hai toan hang
    												if(shift_flag==0)
    													begin	
    													next_op=add;
    													state=to_uniform_state;
    													end
    												else							//phep -
    													begin
    													next_op=sub;												
    													state=to_uniform_state;
    													end 
    												end															
    				/*				mul_sc	:		begin								// hai toan hang
    												if(shift_flag==0)
    													begin	
    													next_op=mul;
    													state=to_uniform_state;
    													end
    												else							//phep :
    													begin
    													next_op=div;												
    													state=to_uniform_state;
    													end  
    												end		*/								// mot toan hang												
    				/*				shift_sc:		begin
    												shift_flag=~(shift_flag);			// chua xoa cac co nay
    												lcd_start_s=1;
    												lcd_sel_s=3'b 110;
    												state=lcd_wait_state;
    												end   */
    								point_sc:		begin								// dau cham thap phan
    												point_flag=1;
    												lcd_start_s=1;
    												lcd_sel_s=3'b 010;					// right shift
    												lcd_val_s=8'h 2E;
    												state=lcd_wait_state;
    												end
    								equal_sc:		begin								// dau =
    												equal=1;
    												next_op=non_op;
    												state=to_uniform_state;
    												end								
    								default	:		;
    								endcase
    							end
    						end
    					end
    				end
    input_state	:	begin
    				if(point_flag==1)
    					begin
    					if(fract_cnt==fract_digit)							// so digit cho phep sau dau cham thap phan
    						state=wait_state;								// tro ve trang thi cho nhap ky tu
    					else
    						begin
    						fract_cnt=fract_cnt+1;
    						input_value=mul_10(input_value)+number_value;
    						lcd_val_s= { 4'b 0011, number_value};
    						lcd_start_s=1;
    						lcd_sel_s=3'b 010;								// dich phai
    						state=lcd_wait_state;
    						end
    					end
    				else
    					begin
    					if(int_cnt==int_digit)								// so digit cho phep truoc dau cham thap phan
    						state=wait_state;								// tro ve trang thi cho nhap ky tu
    					else
    						begin
    						int_cnt=int_cnt+1;
    						input_value=mul_10(input_value)+number_value;
    						lcd_val_s= { 4'b 0011, number_value};
    						lcd_start_s=1;
    						lcd_sel_s=3'b 010;								// dich phai
    						state=lcd_wait_state;
    						end
    					end
    				end
    to_uniform_state:begin													// xu ly gia tri nhap vao cho vo dang a.10^-3
    				shift_flag=0;											// xoa shift
    				if(fract_cnt==fract_digit)	
    					begin
    					point_flag=0;
    					if(cur_op==sub)
    						begin
    							input_value[n]=~input_value[n];
    							cur_op=add;
    						end
    					state=two_opr_state;
    					if (mad==1) 
    					state=phimnho_state;
    					end
    				else
    					begin
    					input_value=mul_10(input_value);
    					fract_cnt=fract_cnt+1;
    					state=to_uniform_state;
    					end
    				end
    two_opr_state:	begin								// do cur_op luu gia tri truoc sau 1 xung clock thi cong tru chung
    				case (cur_op)
    					add	: 	begin
    							return_add=add_sub(result_value[n],input_value[n],result_value[n-1:0],input_value[n-1:0]);
    							state=two_opr1_state;
    							end
    					mul	:	begin
    							return_mul=multiplier(result_value,input_value);
    							state=two_opr1_state;
    							end
    					div	:	begin
    							div1_s[n_div]=result_value[n];
    							div1_s[n_div-1:0]=0;
    							div1_s[n-1:0]=result_value[n-1:0];
    							div2_s=input_value;
    							cur_op=next_op;
    							state=div_S0_state;
    							end
    					non_op:	begin
    							cur_op=next_op;
    							if(equal==1)
    								equal=0;
    							else					// neu khong phaidau bang thi luu ket qua vao ket qua
    								begin
    								result_value=input_value;
    								end
    							lcd_clear_flag=1;
    							state=wait_state;
    							end
    					default:;
    				endcase
    				int_cnt=0;
    				fract_cnt=0;
    				input_value=0;
    				end
    two_opr1_state:	begin									// xu ly ket qua tra ve
    				case (cur_op)
    					add	:	begin
    							if(return_add[n]==1)	 	// tran
    								begin
    								lcd_start_s=1;
    								lcd_sel_s=3'b 100;		// bao loi
    								end
    							else
    								begin
    								lcd_start_s=1;
    								result_value[n]=return_add[n+1];
    								result_value[n-1:0]=return_add[n-1:0];
    								lcd_result_s[n]=return_add[n+1];
    								lcd_result_s[n-1:0]=return_add[n-1:0];								
    								lcd_sel_s=3'b 011;		// hien thi ket qua ra  lcd
    								lcd_clear_flag=1;
    								end
    							state=lcd_wait_state;
    							end
    					mul	:	begin
    							if(return_mul[2*n-1:n_div]!= 33'h 000000000)			// tran
    								begin
    								lcd_start_s=1;
    								lcd_sel_s=3'b 100;									// bao loi
    								state=lcd_wait_state;
    								end
    							else
    								begin
    								div1_s[n_div]=return_mul[2*n];
    								div1_s[n_div-1:0]=return_mul[n_div-1:0];
    								div2_s[n:17]=0;
    								div2_s[16:0]=20'h 186A0;						// 100000
    								state=div_S1_state;
    								end
    							end
    					default:;
    				endcase
    					point_flag=0;
    					cur_op=next_op;
    					int_cnt=0;
    					fract_cnt=0;
    					input_value=0;							// reset lai gia tri nhap
    					end
    					// bo chia
    div_S0_state:		begin								// mul 1000 voi so bi chia												
    					if(div_cnt==5'b 00011)
    							begin
    							div1_s=mul_10_ext(div1_s);
    							div_cnt=div_cnt+1;
    							end
    					else if(div_cnt==5'b 00101)
    						begin
    						div_cnt=0;
    						state=div_S1_state;
    						end
    					else
    						begin
    						div1_s=mul_10_ext(div1_s);
    						div_cnt=div_cnt+1;
    						end
    					end
    div_S1_state:		begin
    					div_cnt=n_div-1;
    					divider[n_div-2:0]=0;				// nhan voi 2^(nSB-1) cua ket qua
    					dividend=div1_s[n_div-1:0];
    					divider[n+n_div-2:n_div-1]=div2_s[n-1:0];
    					state=div_S2_state;
    					end
    div_S2_state:		begin
    					if(divider[n+n_div-2:n_div]!=43'h 00000000000)
    						quotient[div_cnt]=0;
    					else
    						begin
    						if(dividend>=divider[n_div-1:0])
    							begin
    							quotient[div_cnt]=1;
    							dividend=dividend-divider[n_div-1:0];
    							end
    						else
    							quotient[div_cnt]=0;
    						end
    					divider={1'b 0,divider[n+n_div-2:1]};			// n-1 lan lap de tinh duoc n-1 gia tri cua thuong
    					if(div_cnt==0)
    						begin
    						div_cnt=0;
    						quotient[n_div]=div1_s[n_div] ^ div2_s[n];
    						state=div_S3_state;
    						end
    					else
    						begin
    						div_cnt=div_cnt-1;	
    						state=div_S2_state;
    						end
    					end
    div_S3_state:		begin
    						if(quotient[n_div-1:n]!= 17'h 0000)		// tran
    							begin
    							lcd_start_s=1;
    							lcd_sel_s=3'b 100; 						// bao loi
    							state=lcd_wait_state;
    							end
    						else
    							begin
    							result_value[n]=quotient[n_div];	// dau
    							result_value[n-1:0]=quotient[n-1:0];
    							end
    							lcd_result_s[n]=quotient[n_div];		// dau
    							lcd_result_s[n-1:0]=quotient[n-1:0];
    							lcd_start_s=1;
    							lcd_sel_s= 3'b 011;						// hien thi ket qua ra lcd
    							lcd_clear_flag=1;						// bao xoa khi co 1 phim duoc an de nhap moi
    							state =lcd_wait_state;
    					end
    phimnho_state:		begin				
    					mem=add_sub(lcd_result_s[n],mem[n],lcd_result_s[n-1:0],mem[n-1:0]);
    					if(mem[n]==1)	 	// tran
    						begin
    						mem[n]=0;
    						mem[n-1:0]=0;
    						state=lcd_wait_state;
    						end	
    					end
    hienthi_state :		begin
    						lcd_start_s=1;
    						lcd_result_s[n]=mem[n+1];
    						lcd_result_s[n-1:0]=mem[n-1:0];								
    						lcd_sel_s=3'b 011;		// hien thi ket qua ra  lcd
    						lcd_clear_flag=1;
    						state=lcd_wait_state;
    					end
    wait_state :		begin											// trang thai cho scan code ready xuong 0
    					if(data_ready==0)
    						state=scancode_state;
    					else
    						state=wait_state;
    					end
    					default:			;
    endcase
    end
    endmodule

  • #2
    Ai mà đọc nổi đoạn code này ... bạn post máy trạng thái + sơ đồ khối lên đi ...

    Comment

    Về tác giả

    Collapse

    honulolo Tìm hiểu thêm về honulolo

    Bài viết mới nhất

    Collapse

    Đang tải...
    X