基於modelsim的alu運算器編寫(verilog語言)

源文件:


module alu5(ena, clk, opcode, a, b, c,d);

	parameter N = 32; 
	//狀態編碼
	parameter sla=3'b000,
	sra=3'b001,
	add=3'b010,
	sub=3'b011,
	mul=3'b100,
	andd=3'b101,
	ord=3'b110,
	notd=3'b111;
	
	//定義輸入輸出端口
	input ena, clk;
	input [2 : 0] opcode;
	input signed [N - 1 : 0] a, b; //輸入有符號整數範圍爲[-128, 127] 
	output signed[N-1:0] c;
	output signed[2:0] d;
	
	//內部寄存器定義
	reg signed [N : 0] temp;
	reg cf;
	reg [5:0] ii;
	reg signed [N-1:0] c;
	reg signed [2:0] d;
	
	//邏輯實現
	always@(posedge clk)
	begin
		if(ena)
		begin
			casex(opcode)
				sla:
					begin
					  c={a[31],a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1],a[0],1'b0};
					  if({a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1],a[0]}==30'b000000000000000000000000000000)
					  	d[0]=1'b1;
					  else
					  	d[0]=1'b0;
					  if(a[N-1]==1'b1)
					  	d[2]=1'b1;
					  else
					  	d[2]=1'b0;
					  d[1]=1'bz;
					end
				sra:
					begin
					  c={a[31],a[31],a[30],a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1]};
					  if({a[31],a[30],a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1]}==31'b0000000000000000000000000000000)
					  	d[0]=1'b1;
					  else
					  	d[0]=1'b0;
					  if(a[N-1]==1'b1)
					  	d[2]=1'b1;
					  else
					  	d[2]=1'b0;
					  d[1]=1'bz;
					end
				add:
					begin
					  temp=0;
					  temp={1'b0,a[N-1:0]}+{1'b0,b[N-1:0]};
					  c=temp[N-1:0];
					  cf=temp[N];
					  d[1]=c[N-1]^a[N-1]^b[N-1]^cf;
					  if(c==32'h00000000)
					  	d[0]=1'b1;
					  else
					  	d[0]=1'b0;
					  if(c[N-1]==1'b1)
					  	d[2]=1'b1;
					  else
					  	d[2]=1'b0;
					 end
				sub:
					begin
					  temp=0;
					  temp={1'b0,a[N-1:0]}-{1'b0,b[N-1:0]};
					  c=temp[N-1:0];
					  cf=temp[N];
					  d[1]=c[N-1]^a[N-1]^b[N-1]^cf;
					  if(c==32'h00000000)
					  	d[0]=1'b1;
					  else
					  	d[0]=1'b0;
					  if(c[N-1]==1'b1)
					  	d[2]=1'b1;
					  else
					  	d[2]=1'b0;
					 end
				mul:
					begin
					  c=0;
					  for(ii=0;ii<32;ii=ii+1)
						if(b[ii])
						  c=c+(a<<(ii));
					  if(c==32'h00000000)
						d[0]=1'b1;
					  else
						d[0]=1'b0;
					  d[2]=a[31]^b[31];
					  d[1]=1'bz;
					end
				andd:
					begin
					  c=a&b;
					  if(c==32'h00000000)
						d[0]=1'b1;
					  else
						d[0]=1'b1;
					  d[2]=1'b0;
					  d[1]=1'b0;
					end
				ord:
					begin
					  c=a|b;
					  if(c==32'h00000000)
						d[0]=1'b1;
					  else
						d[0]=1'b0;
					  d[2]=1'b0;
					  d[1]=1'b0;
					end
				notd:
					begin
					  c=~a;
					  if(c==32'h00000000)
						d[0]=1'b1;
					  else
						d[0]=1'b0;
					  d[2]=1'b0;
					  d[1]=1'b0;
					end
				default: c<=0;

			endcase
		end
	end
endmodule

測試文件:

`timescale 1ns/1ns
`define half_period 5
module alu_t5(c,d);
	//alu位寬定義
	parameter N = 32;
	parameter sla=3'b000,
	  sra=3'b001,
	  add=3'b010,
	  sub=3'b011,
	  mul=3'b100,
	  andd=3'b101,
	  ord=3'b110,
	  notd=3'b111;
	
	//輸出端口定義
	output signed [N-1 : 0] c;
	output signed [2 : 0] d;
	
	//寄存器及連線定義
	reg ena, clk;
	reg [2 : 0] opcode;
	reg signed [N - 1 : 0] a,b;
	
	//產生測試信號
	initial
	begin
		//設置電路初始狀態
		#20 clk = 0; ena = 0; opcode = 3'b000;
			a = 32'd0; b = 32'd0;
		#20 ena = 1;
		
		//test sla
		#20 a=32'hdffffffd;
	    opcode=sla;
		#20 a=32'h4ffffff0;
	    opcode=sla;
		
		//test sra
		#20 a=32'hfffffffd;
	    opcode=sra;
		#20 a=32'h3ffffff9;
	    opcode=sra;
		
		//test add
		#20 a=32'd1000;
	    b=32'd2000;
	    opcode=add;
		#20 a=32'd2000;
	    b=-32'd5000;
	    opcode=add;
		#20 a=-32'd120000;
	    b=-32'd10000;
	    opcode=add;
		#20 a=32'd6000;
	    b=-32'd6000;
	    opcode=add;
		
		//test sub
		#20 a=32'd6000;
	    b=32'd5000;
	    opcode=sub;
		#20 a=32'd2000;
	    b=32'd4000;
	    opcode=sub;
		#20 a=32'd8000;
	    b=32'd8000;
	    opcode=sub;
		
		//test mul
		#20 a=32'd100;
	    b=32'd100;
	    opcode=mul;
		#20 a=-32'd200;
	    b=32'd300;
	    opcode=mul;
		#20 a=-32'd400;
	    b=-32'd200;
	    opcode=mul;
		
		//test and
		#20 a=32'h0101_1101;
	    b=32'h1100_0110;
	    opcode=andd;
		#20 a=32'h1101_1001;
	    b=32'h0010_0110;
	    opcode=andd;
		
		//test or
		#20 a=32'h0111_0011;
	    b=32'h0001_1011;
	    opcode=ord;
		#20 a=32'h1111_0000;
	    b=32'h1111_1111;
	    opcode=ord;
		
		//test not
		#20 a=32'h1111_0000;
	    opcode=notd;
		#20 a=32'h1111_1111;
	    opcode=notd;
		
		
		#100 $stop;
	end
	
	//產生時鐘
	always #`half_period clk = ~clk;
	
	//實例化
	alu5 m0(.ena(ena), .clk(clk), .opcode(opcode), .a(a), .b(b), .c(c), .d(d));
endmodule

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章