Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

help with code for a newbie...:)

Status
Not open for further replies.

toffee_pie

Newbie level 6
Joined
Oct 31, 2009
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,419
greetings all,

can anyone with verilog skills help me implement this ALU, I wish to firstly get the basic operations functioning before i move onto the more difficult tasks.

It wont compile, I am getting an error with the endmodule part? also do I need another reg to store the overflow bit and work out signed and unsigned outputs?



// VERILOG CODE


// 'timescale 10ns

module ALU (a,b,Cin,Op,clk,resetb,C[s+15:0],s,ov)


output signed C[s + 15:0] ; // 2's compliment signed 16 bit output word

output ov; // The result of addition or subtraction is
// supposed to fit
// within the significant bits used to represent the numbers.
// If ‘n’ bits are used to represent signed numbers
// in 2’s complement
// scheme, then the result must be in the range
// –2n-1 to 2n-1-1.
// If the result does not fit in this range, then an arithmetic
// overflow has occurred, this used for signed operations.


input clk,resetb; // system clock @ 100Mhz , synchronous
// system reset active low
input [2:0] Op; // assigns ALU one of its 8 operand Instruction
input [15:0] a,b; // unsigned 16 bit input operands to ALU
input Cin,s ; // Carry in, Sum In


// internal nodes

wire [15:0] a,b;
reg signed [15:0] c; // output reg
reg signed s;
reg signed ov;


parameter WIDTH = 'd16;

parameter ADD_AB = 3'b000; // addition -> c = a + b
parameter SUB_AB = 3'b001; // subtraction -> c = a - b
parameter MUL_AB = 3'b010; // multiplication -> c = a * b
parameter AND_AB = 3'b011; // and -> c = a & b
parameter OR_AB = 3'b100; // or -> c = a | b
parameter XOR_AB = 3'b101; // xor -> c = a ^ b
parameter SHIFT_LEFT_A = 3'b110; // shift left -> c = a >> 1
parameter SHIFT_RIGHT_A = 3'b111; // shift right -> c = b >> 1



always @ (a or b or op) begin

// Lets do Arithmetic operations

begin

if (op[2:1] == 2'b00) begin

case (op[2:0])

3'b000:c = a + b ; // addition
3'b001:c = a - b ; // subtraction
//3'b010:c = a * b ; //
default:c = 16'bx;

endcase

//overflow = c[15]^c[14];

end


// Lets do Logical operations

else if (op[2:1] == 2'b01) begin

case (op[2:0])

3'b011:c = a & b ; // logical and
3'b100:c = a | b ; // logical or
3'b111:c = a ^ b; // logical exor
default:c = 16'bx;


endcase

endmodule
 

sorry i didn't look at the FULL code yet, but i did notice a few things in the beginning. I'm a noob too, so I'm not sure how much help i can be, but:
1) output overflow isn't in your list of IO in the module's "sensitivity list"(sorry i forget the name and i want to say parameter list as if it were C).
2)IIRC, a 16-bit SIGNED input would be something like
Code:
input [12:-3] a,b;
3) i also think that you would need some extra room for carry, like
Code:
 input [13:-3] a,b;
so that you can say
Code:
 (a[13]) ? carry_flag_set : carry_flag_clear;
I hope you get what i'm saying. And I hope im not confusing you.
Good luck.
 

Hi ya,

thanks for the help, yes I understand. I was wondering about the extra 'bit' for the carry operation...:|

the two inputs a,b are 'unsigned'

the output, c is 'signed'. [s + 15:0]

does that mean the output is 17 bits?

I have included the ov term for overflow in the declarations.

I would like to get the basics going before I worry about the shift operations and the multiply operand, which needs tweaking or 'chopping' as the output answer may exceed 16 bits.
 

toffee_pie said:
the output, c is 'signed'. [s + 15:0]
does that mean the output is 17 bits?
If s represents 1 bit then yes :) i'm not sure what 's'
means or if it's syntactically correct, verilog-wise.
I've been meaning to learn how to write an ALU myself. I could use this as an
excuse to read up on signed numbers in verilog :)

hmm check out page 190 section 7.3.3 can it be that easy?? :)
 

s is to signify a signed o/p i presume...


in verilog all declarations are unsigned for default, so you need to tell if they are signed,

so i had to say signed for the output to let it know.

how I deal with regs and storage is another thing, and If i can implement this in one always loop....
 

my thing is i don't see any parameter declared named 's' or know of any keyword called 's' in verilog.
 

ha,

thats correct...!

c[s + 15:0] is the output

where s is the 2 signed compliment output word

so that can be amended to my code.

I am not sure what I do with this S, and how I declare it ?

its a > 'reg signed s' I would think ?

1 bit word? is this declared just as in output reg..?
 

i'm sorry i'm not sure i understand your question.
are you saying you want a sign bit?
 

I have attached a block diag of my design.

I have also used a updated block of the final product as the original misses out on carry inputs etc.

I changed my code also, slightly regarding the port declarations.
 

hello, haven't had a chance to look at your code yet(you might have noticed that i'm steadily working on something posted in these forums for myself.)
what I DID do though, was look for some info for my project and stumble upon this:
**broken link removed**
a tuto for a signed ALU
good luck :)
 

well,

I have been over complicating my code way too much. I dont need any carry, sum flags or regs.

Making it too complicated for my own sake. The output is a 16 bit word, plus 1 bit for the 2s compliment bit.

[msb].................[lsb]
 

hello

Yes, I got my code working. well i got it synthised on xilinx ise

I need to create a test bench for it now and having problems.

an someone help me with the test bench for this please? I ran it on multi sim and got an error to do with the c bit being the incorrect size and a few other things mentioning incorrect sizes also.

I have two 'c' variables in my code, one is c_nx= the output of the alu, which is sent to the ff to be timed, the output of this is the actual port output 'c'

so c_nx is not declared as an output.

anyone?



module ALU(a,b,op,clk,resetb,c);


parameter s = 'd1;
output signed[s+15:0]c;
reg signed[s+15:0]c;



input [15:0]a,b;
input [2:0]op;
input resetb;
input clk;



reg signed [s+15:0]c_nx;
//output signed [s+15:0]c_nx;




// port declarations



parameter WIDTH = 'd16;

parameter ADD_AB = 3'b000; // addition -> c = a + b
parameter SUB_AB = 3'b001; // subtraction -> c = a - b
parameter MUL_AB = 3'b010; // multiplication -> c = a * b
parameter AND_AB = 3'b011; // and -> c = a & b
parameter OR_AB = 3'b100; // or -> c = a | b
parameter XOR_AB = 3'b101; // xor -> c = a ^ b
parameter SHIFT_LEFT_A = 3'b110; // shift left -> c = a >> 1
parameter SHIFT_RIGHT_B = 3'b111; // shift right -> c = b >> 1


always @(a or b or op)

case (op)

ADD_AB: c_nx = a + b;
SUB_AB: c_nx = a - b;
MUL_AB: c_nx = a * b;
AND_AB: c_nx = a & b;
OR_AB: c_nx = a | b;
XOR_AB: c_nx = a ^ b;
SHIFT_LEFT_A: c_nx = a >> 1;
SHIFT_RIGHT_B: c_nx = b >> 1;

endcase

always @ (posedge clk)

if (~resetb)

c <= 0;

else

c <= c_nx;

endmodule

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

module ALU_tb ( // no ports; this is a testbench
);


parameter PRD = 10; // ns - according to left-hand argument to the timescale directive
parameter SIMLEN = 100; // clks - number of clks for which to run the simulation

parameter s = 'd1;
parameter WIDTH = 'd16;


// inputs to the DUT are reg types


reg clk,resetb;
reg [15:0]tb_a,tb_b,true_output;
reg [2:0]tb_op;

// outputs from the DUT are wire type

wire signed[15:0]tb_c;

integer i,j,outfile,pat_error;

// instantiate the device under test

ALU my_alu_testbench(.c(tb_c),.a(tb_a),.b(tb_b),.op(tb_op),.resetb(resetb),.clk(clk));

always #5 clk = ~clk; // every 5 nano seconds invert, create period 10ns

initial

begin

$monitor (tb_a,tb_b,tb_c);

outfile = $fopen("tb_c.txt");

if(!outfile) begin

$display("can not write file!");

$finish;

end

pat_error= 0;

resetb= 1'b1;clk=1'b1;a=0;b=0;op=0;

#2 resetb = 1'b0;

#2 resetb = 1'b1;


// test for instruction add


op = 3'b000;

for (i=0;i<65536;i=i+1)

begin

for (j=0;j<65536;j=j+1)

begin

a = i[15:0];b=j[15:0];

#10 true_output = a + b;

if(c!==true_output[15:0])

begin

$fdisplay (outfile, "%b + %b should be %b. but your output is %b." , a,b,true_output,c);

pat_error= pat_error+1;

end
end
end

end


endmodule
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top