| Author |
Message |
toffee_pie
Joined: 01 Nov 2009 Posts: 9
|
01 Nov 2009 0:41 help with code for a newbie...:) |
|
|
|
|
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
Last edited by toffee_pie on 01 Nov 2009 23:15; edited 3 times in total |
|
| Back to top |
|
 |
laserbeak43
Joined: 15 Aug 2008 Posts: 24 Location: Maryland, USA
|
01 Nov 2009 1:01 help with code for a newbie...:) |
|
|
|
|
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
3) i also think that you would need some extra room for carry, like
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.
|
|
| Back to top |
|
 |
toffee_pie
Joined: 01 Nov 2009 Posts: 9
|
01 Nov 2009 1:23 Re: help with code for a newbie...:) |
|
|
|
|
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.
|
|
| Back to top |
|
 |
laserbeak43
Joined: 15 Aug 2008 Posts: 24 Location: Maryland, USA
|
01 Nov 2009 2:44 Re: help with code for a newbie...:) |
|
|
|
|
| toffee_pie wrote: |
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??
|
|
| Back to top |
|
 |
toffee_pie
Joined: 01 Nov 2009 Posts: 9
|
01 Nov 2009 2:51 Re: help with code for a newbie...:) |
|
|
|
|
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....
|
|
| Back to top |
|
 |
Google AdSense

|
01 Nov 2009 2:51 Ads |
|
|
|
|
|
|
| Back to top |
|
 |
laserbeak43
Joined: 15 Aug 2008 Posts: 24 Location: Maryland, USA
|
01 Nov 2009 2:58 help with code for a newbie...:) |
|
|
|
|
| my thing is i don't see any parameter declared named 's' or know of any keyword called 's' in verilog.
|
|
| Back to top |
|
 |
toffee_pie
Joined: 01 Nov 2009 Posts: 9
|
01 Nov 2009 3:05 Re: help with code for a newbie...:) |
|
|
|
|
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..?
|
|
| Back to top |
|
 |
laserbeak43
Joined: 15 Aug 2008 Posts: 24 Location: Maryland, USA
|
01 Nov 2009 5:18 help with code for a newbie...:) |
|
|
|
|
i'm sorry i'm not sure i understand your question.
are you saying you want a sign bit?
|
|
| Back to top |
|
 |
toffee_pie
Joined: 01 Nov 2009 Posts: 9
|
01 Nov 2009 23:05 Re: help with code for a newbie...:) |
|
|
|
|
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.
|
|
| Back to top |
|
 |
laserbeak43
Joined: 15 Aug 2008 Posts: 24 Location: Maryland, USA
|
02 Nov 2009 5:08 help with code for a newbie...:) |
|
|
|
|
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:
http://people.tamu.edu/~rajballavdash/lab_manual_3_4.pdf
a tuto for a signed ALU
good luck
|
|
| Back to top |
|
 |
toffee_pie
Joined: 01 Nov 2009 Posts: 9
|
03 Nov 2009 2:27 Re: help with code for a newbie...:) |
|
|
|
|
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.
[s][msb].................[lsb]
|
|
| Back to top |
|
 |
dcreddy1980
Joined: 03 Dec 2004 Posts: 189 Helped: 25 Location: Munich, Germany
|
06 Nov 2009 12:52 help with code for a newbie...:) |
|
|
|
|
| did u solve your problem, if not let me know.
|
|
| Back to top |
|
 |
toffee_pie
Joined: 01 Nov 2009 Posts: 9
|
06 Nov 2009 14:40 Re: help with code for a newbie...:) |
|
|
|
|
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
|
|
| Back to top |
|
 |