EmbDev.net

Forum: FPGA, VHDL & Verilog 8 bit Arithmetic Logic Unit


von neha s. (neha_s)


Rate this post
useful
not useful
module div8(output [7:0]divd, output zeroerror, input [7:0]a, input 
[7:0]b);
assign {zeroerror,divd} = b ? a/b : 9'b1xxxxxxxx;
endmodule
/////////
module modulus8(output [7:0]remainder, output zeroerror, input [7:0]a, 
input [7:0]b);
assign {zeroerror,remainder} = b ? a%b : 9'b1xxxxxxxx;
endmodule
/////////
module mul8(output [7:0]prod, output overflow, input [7:0]a, input 
[7:0]b);
assign {overflow,prod} = a*b;
endmodule
////////
module sub8(output [7:0]d, output bout, input [7:0]a, input [7:0]b, 
input bin);
  assign {bout,d}=a-b-bin;
endmodule
/////////
module add8(output [7:0]sum, output cout, input [7:0]a, input [7:0]b, 
input cin);
  assign {cout,sum}=a+b+cin;
endmodule
/////////
module shiftleft8(output [7:0]out,input [7:0]a);
  assign out = a<<1;
endmodule
//////////
module shiftright8(output [7:0]out,input [7:0]a);
  assign out = a>>1;
endmodule
/////////
module buf8(output [7:0]OUT,input [7:0]a);
  assign #10 out =  a;
endmodule
module alu(output [7:0]R, inout [2:0]S, input [3:0]cntrl,input 
[7:0]A,input [7:0]B);
  parameter CNTRL=cntrl;
    generate
      if(CNTRL==4'd0)
      buf8 b1(R,A);
    else if(CNTRL==4'd1)
      add8 a1(R,S[0],A,B,S[0]);
    else if(CNTRL==4'd2)
      sub8 s1(R,S[0],A,B,S[0]);
    else if(CNTRL==4'd3)
       div8 d1(R,S[1],A,B);
    else if(CNTRL==4'd4)
       modulus8 m2(R,S[1],A,B);
    else if(CNTRL==4'd5)
       shiftleft8 s1(R,A);
    else if(CNTRL==4'd6)
       shiftright8 s2(R,A);
    else
       mul8 m1(R,S[2],A,B);
  endgenerate
endmodule


//// using generate system requires CNTRL to be a constant. which i am 
not able to achieve. also if i use use simple case or if statements it 
doesnt read my instantiations. i am stuck. what should i do for the 
conditions. help please.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
You do not really want to generate the modules just in time when 
they are needed!
Generate tells the synthesizer whether to generate a module on the FPGA 
or not. But you want to have all of the modules and just switch 
between them. So usually you instantiate all of the modules. Then you 
supply all of the modules with the input values. And you just 
multiplex the results.
Why don't you just look how the thousands other ALUs around there in the 
world are done?

von neha s. (neha_s)


Rate this post
useful
not useful
module div8(output [7:0]divd, output zeroerror, input [7:0]a, input 
[7:0]b);
assign {zeroerror,divd} = b>0 ? a/b : 9'b1xxxxxxxx;
endmodule

module modulus8(output [7:0]remainder, output zeroerror, input [7:0]a, 
input [7:0]b);
assign {zeroerror,remainder} = b ? a%b : 9'b1xxxxxxxx;
endmodule

module mul8(output [7:0]prod, output overflow, input [7:0]a, input 
[7:0]b);
assign {overflow,prod} = a*b;
endmodule

module sub8(output [7:0]d, output bout, input [7:0]a, input [7:0]b, 
input bin);
  assign {bout,d}=a-b-bin;
endmodule

module add8(output [7:0]sum, output cout, input [7:0]a, input [7:0]b, 
input cin);
  assign {cout,sum}=a+b+cin;
endmodule

module shiftleft8(output [7:0]out,input [7:0]a);
  assign out = a<<1;
endmodule

module shiftright8(output [7:0]out,input [7:0]a);
  assign out = a>>1;
endmodule

module buf8(output [7:0]OUT,input [7:0]a);
  assign #10 out =  a;
endmodule
module alu(output [7:0]RES, output [2:0]S, input [2:0]CNTRL,input 
[7:0]A,input [7:0]B,input CIN);
      wire [7:0]R[7:0];
      buf8 b1(R[0],A);
      add8 a1(R[1],S[0],A,B,CIN);
      sub8 s1(R[2],S[0],A,B,CIN);
      div8 d1(R[3],S[1],A,B);
      modulus8 m2(R[4],S[1],A,B);
      shiftleft8 s2(R[5],A);
      shiftright8 s3(R[6],A);
      mul8 m1(R[7],S[2],A,B);
      assign RES = ((CNTRL[2]==0) ? (CNTRL[1]==0 ? (CNTRL[0]==0 ? R[0] : 
R[1]) : (CNTRL[0]==0 ? R[2] : R[3])) : (CNTRL[1]==0 ? (CNTRL[0]==0 ? 
R[4] : R[5]) : (CNTRL[0]==0 ? R[6] : R[7])));
endmodule
 module simulate_alu;
   reg [2:0]cntrl;
   wire [2:0]s;
   reg [7:0]a,b;
   wire [7:0]res;
   reg cin;
   initial
   begin
   $monitor($time,"%d %d %d",res,a,b);
   end
   alu a1(res,s,cntrl,a,b,cin);
   initial
   begin
     a=8'd4; b=8'd2; cntrl=3'd0;
     #10
     #10 a=8'd4; b=8'd2; cntrl=3'd0;
     #10 a=8'd4; b=8'd2; cntrl=3'd1; cin =1'b1;
     #10 a=8'd4; b=8'd2; cntrl=3'd2; cin =1'b0;
     #10 a=8'd4; b=8'd2; cntrl=3'd3;
     #10 a=8'd4; b=8'd2; cntrl=3'd4;
     #10 a=8'd4; b=8'd2; cntrl=3'd5;
     #10 a=8'd4; b=8'd2; cntrl=3'd6;
     #10 a=8'd4; b=8'd2; cntrl=3'd7;
   end
 endmodule
// with you advice i made some changes and now its working fine. just 
divide function needs to be corrected. thanks for your help.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
> with you advice i made some changes and now its working fine.
Nice to hear.
> just divide function needs to be corrected.
Yes, because a division is not that simple in hardware. Have a look at 
the ressources of your design. What target do you have?

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.