EmbDev.net

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


Author: neha s. (neha_s)
Posted on:

Rate this post
0 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.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 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?

Author: neha s. (neha_s)
Posted on:

Rate this post
0 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.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 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?

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.