Rounding of bits during different arithmetic operation in verilog? - verilog

I am new to HDL coding.
I have a problem regarding rounding and there are different types of rounding available, like Round half away from zero, Round half to even, Round half to odd etc. (found in https://en.wikipedia.org/wiki/Rounding). I wrote a verilog code of rounding for my multiplication, addition etc. with the help of internet and the code is working properly. But, I want to know what type of rounding the code is performing. Whether it is Round half to odd or Round half to even or anything else. Can anybody tell me what type of rounding the code is performing? The code is given below
`timescale 1ns / 1ps
module rounding();
parameter x = 16;
parameter y = 8;
reg [(x)-1:0] A=16'b0010011010110011;
reg [(x)-1:0] B;
initial begin
B = (A[y-1:0]) >= (1 << y-1) ? (A >>> y) + 1 : (A >>> y);
$display("%b", B);
end
endmodule
If I give input A=16'b0010011010110011; output is coming as 0000000000100111;
if A=16'b0000111100001111; output is coming as 0000000000001111

Your code divides input value A by 256 and apply rounding to the nearest integer:
A=16'b0010011010110011 -> 9907 (dec) -> 9907/256 = 38.69 (round up) ~ 39 -> 0000000000100111
A=16'b0000111100001111 -> 3855 (dec) -> 3855/256 = 15.06 (round down) ~ 15 -> 0000000000001111

Related

ECLiPSe CLP produces variable with unexpected range

I have a question regarding the following code:
:-lib(ic).
buggy_pred(Result, In0, In1, In2, In3, In4, In5, In6, In7) :-
Args = [In0, In1, In2, In3, In4, In5, In6, In7],
Args :: [0..255],
Result :: [0..18446744073709551615], % 64bits wide
% put 8 bytes together to form a 64-bit value
Result #= (In0 + (In1 * 256) + (In2 * 65536) + (In3 * 16777216) + (In4 * 4294967296) +
(In5 * 1099511627776) + (In6 * 281474976710656) + (In7 * 72057594037927936)).
buggy_pred_test :-
buggy_pred(Result, 56, 8, 0, 0, 16, 0, 0, 1),
get_bounds(Result, Lo, Hi),
write(Lo), nl,
write(Hi).
Should not the above code (predicate buggy_pred_test) print two same numbers? In this case it yields two numbers (Lo and Hi respectively) which are different:
72057662757406720
72057662757406800
I cannot figure out what is the cause of that behaviour. I am using ECLiPSE 6.1 #194, x86_64 for linux. Your help is greatly appreciated.
ECLiPSe's lib(ic) constraint solver is designed for handling mixtures of real- and integer-valued variables/constraints. All computations are performed using double floats to represent upper and lower bounds, even integer operations (integrality is simply treated as an additional constraint).
Because double floats have 53 bits of precision, only integers in the range -9007199254740991..9007199254740991 can be represented precisely. Larger integers are approximated by a floating point interval that encloses the true value. This is why you get a non-zero-width interval as a result.
This may sound unsatisfactory, but in practice models involving huge integer domains are rarely efficiently solvable, and are therefore less useful than they may seem. So, the advice would be to model the problem differently, see
here for an example of modeling a problem in two ways.

Using " * " for multiplication of binary numbers, only gives me addition, why? (Code here)

I'm learning operations with " + ", " - " and " * ", addition and subtraction works well, but multiplication gives me only additions, link for the code:
http://www.edaplayground.com/x/NvT
I checked the code, can't understand what's going on. I gave enough space (bits) the result variable.
BTW, It's a code intended for fixed-point operations including fractional numbers, but everything is calculated as integers.
Your select signal is only on 1bit.
Then when you set select = 2 it assigns the lower bit of 2(2'b10) i.e. 0.
You should change select declaration by :
input [1:0] select; // In the module
reg [1:0] select; // In the testbench
To avoid such errors I would advise you to use the complete notation of values:
x'tnnn...nnn
where x is the width of the signal, t is the type (d for decimal, h for hexa, b for binary,...) and nnn...nnn the value in the type specified.
For example for the decimal value 2 you will have several notations that will make sense in certain situations:
2'd2 //2 bits decimal
2'h2 //2 bits hexadecimal
2'b10//2 bits binary
For more informations about these notations you can read this pdf.

Finding a remainder using division of 10

I need to find the right most bit of any integer. So, i can find the remainder of the value divided by 10 (i.e) a = rem(Num1,10); in Matlab.. How to do the same using Verilog . I have Xilinx 14.1 and 9.1..
% is the modulus operator in verilog, just like in C
looking at the comments, it looks like you want to make a rounding function: here's something that will do that:
One note: the code below will be VERY inefficient since % is expensive in hardware. Consider dividing by a power of 2 like 8 or 16 instead of 10.
module round
(
input wire[31:0] x,
output reg[31:0] rounded
);
reg[31:0] remainder;
always #(*) begin
// % operator is VERY slow and expensive!!!
remainder = (x % 32'd10);
// the lines below are decently efficient
if (remainder < 32'd5)
rounded = x - remainder;
else
rounded = x + (32'd10 - remainder);
end
endmodule

How to implement an n-bit adder whose input vectors are represented in octal?

I'm somewhat stumped on this problem:
"Write a verilog module for full addition of n-bit integers. Let the parameter, the number of bits, equal 3. Call this module from a test bench, and in the test bench specify the numbers to be added in the arrays. Assign octal values to the X and Y arrays. The carryin is 0."
And yes, this is homework.
I was able to write the module for the n-bit adder:
module addern(carryin, X, Y, S, carryout, overflow);
parameter n = 3;
input carryin;
input [n-1:0] X, Y;
output reg [n-1:0] S;
output reg carryout, overflow;
always #(X,Y, carryin)
begin
{carryout, S} = X + Y + carryin;
overflow = (X[n-1] & Y[n-1] & ~S[n-1]) | (~X[n-1] & ~Y[n-1] & S[n-1]);
end
endmodule
I understand this component of the problem. However, I'm not sure how to implement the octal number addition. Is there a way in verilog to indicate that the arrays are holding octal values, rather than binary?
Is there anything like a typecast in verilog? For instance, input (octal) [n-1:0] X, Y, and do something likewise in the test bench.
Any constructive input is appreciated.
I'm pretty sure I'm in the same class as you. I think what you need to do is create a hierarchical Verilog module and then assign your values there. That would be your testbench. for example if you want to make X you write input [n-1:0] X = 3'o013, or maybe it's X = 9'o013 if Oli is correct. you don't change n, but it's kind of like BCD where they are in groups and you have a certain amount of bits you can represent before it overflows.
To help solve the problem thik about the question:
Q) How are numbers stored in digital hardware?
A) Binary, in digital logic we can only represent 2 values 1 and 0, but with this we can represent Integer, fixed point or floating point numbers.
Therefore digital numbers are base 2 (two possible values), while being able to represent any number. Other bases such as Octal (base 8) hex (base 16) and decimal (base 10) exist but these are just way of representing numbers, similar to the way binary just represents a number.
A decimal 1, is represented by 1 n all the bases, and when stored as binary they are all the same. An example of some values in verilog and there binary equivalents.
Octal Decimal Hex Binary
3'O7 => 3'd7 => 3'h7 => 3'b111
6'O10 => 6'd8 => 6'h8 => 6'b001000
Octal, Decimal and Hex in verilog are just representations of a binary format, a way of viewing the data. Since the low level electronics has no way of representing any thing other than 0 and 1.
The interesting thing about Octal and Hex is that they have a power of 2 values so they use an exact number of bits so an 9'O123 is the same as treating each Octal place separately and concatenating them together, 9'O123 == {3'O1, 3'O2, 3'O3}. This is also true for hexadecimal values but not decimal (base 10) values, as 10 is not a power of 2 and does not fully occupy the number space.
This does allow 'Octal' ports to be created, which are just 3 bit binary ports:
module octal_concat (
input [2:0] octal_2,
input [2:0] octal_1,
input [2:0] octal_0,
output [8:0] concat
);
assign concat = {octal_2, octal_1, octal_0};
endmodule
octal_concat octal_concat_0 (
.octal_2(3'O1),
.octal_1(3'O2),
.octal_0(3'O3),
.concat() //Drives 9'O123 which is also 9'b001_010_011
);

Verilog reg assignment to part of another reg

I am using Verilog with modelSim and I get the following errors when I try to assign reg variables to different parts of another reg variable:
** Error: Range width must be greater than zero.
** Error: Range width must be constant expression.
here is the relevant code:
integer f; //zd, qd, R and Q are regs
always # * begin
f = 52 - zd;
R = qd[f +:0];
Q = qd[63 -:f+1];
end
I want R to include qd (from 0 to f) and Q to be (the rest) qd (from f+1 to 63). How to do it? Thanks.
What you are trying to do is not legal in verilog 2001.
As your warning says, Range width must be constant expression, i.e. you cannot have variable length part selects.
You can have fixed length part select that varies the starting point (i.e. select 8 bits starting from f), but the syntax for that is this:
vector_name[starting_bit_number +: part_select_width]
vector_name[starting_bit_number -: part_select_width]
In hardware the size of a bus must be a fixed size, you cannot change the number of wires in silicon based on the contents of a register :)

Resources