Related
I need another set of eyes to tell me what is wrong with my Eiffel implementation of Burnikel and Ziegler's division, specifically "Algorithm 2 - 3n/2n". The Eiffel feature is shown below. The type "like Current" is an ARRAYED_LIST [NATURAL_8]. In other words, the implementation uses digits (i.e. limbs) containing 8-bit values, so numbers are in base-256. A manual trace of a failing call follows. (Sorry the arguments are so large, but I cannot reproduce the error with shorter values.) Execution follows step 3b in this case.
Here's the problem. The algorithm seems to be fine to Step 5, where the remainder "r" ends up with more digits then the divisor. I believe the error is in step 3b, perhaps with the call to feature `ones' which is "supposed" to supply a value that is "Beta^n - 1". (Maybe I do not understand B&Z's "Beta^n" notation.
Here is the Eiffel code:
three_by_two_divide (a, a3, b: like Current): TUPLE [quot, rem: like Current]
-- Called by `two_by_one_divide'. It has similar structure as
-- `div_three_halves_by_two_halfs', but the arguments to this
-- function have type {JJ_BIG_NATURAL} instead of like `digit'.
-- See Burnikel & Zieler, "Fast Recursive Division", pp 4-8,
-- Algorithm 2.
require
n_not_odd: b.count >= div_limit and b.count \\ 2 = 0
b_has_2n_digits: b.count = a3.count * 2
a_has_2n_digits: a.count = a3.count * 2
local
n: INTEGER
a1, a2: like Current
b1, b2: like Current
tup: TUPLE [quot, rem: like Current]
q, q1, q2, r, r1: like Current
c, d: like Current
do
n := b.count // 2
-- 1) Split `a'
a1 := new_sub_number (n + 1, a.count, a)
a2 := new_sub_number (1, n.max (1), a)
-- 2) Split `b'.
b1 := new_sub_number (n + 1, b.count, b)
b2 := new_sub_number (1, n.max (1), b)
-- 3) Distinguish cases.
if a1 < b1 then
-- 3a) compute Q = floor ([A1,A2] / B1 with remainder.
if b1.count < div_limit then
tup := school_divide (a, b1)
else
tup := two_by_one_divide (a, b1)
end
q := tup.quot
r1 := tup.rem
else
-- 3b) Q = beta^n - 1 and ...
q := ones (n)
-- ... R1 = [A1,A2] - [B1,0] + [0,B1] = [A1,A2] - QB1.
r1 := a + b1
if n > 1 then
b1.shift_left (n)
else
b1.bit_shift_left (zero_digit.bit_count // 2)
end
r1.subtract (b1)
end
-- 4) D = Q * B2
d := q * b2
-- 5) R1 * B^n + A3 - D. (The paper says "a4".)
r1.shift_left (n)
r := r1 + a3 - d
-- 6) As long as R < 0, repeat
from
until not r.is_negative
loop
r := r + b
q.decrement
end
check
remainder_small_enough: r.count <= b.count
-- because remainder must be less than divisor.
end
Result := [q, r]
ensure
-- n_digit_remainder: Result.rem.count = b.count // 2
quotient_has_correct_count: Result.quot.count <= b.count // 2
end
In the trace, the arrow points to a line I believe is bad, but I don't know what to do with it. Here is the trace:
three_by_two_divide (a = [227,26,41,95,169,93,135,110],
a3 = [92,164,19,39],
b = [161,167,158,41,164,0,0,0])
n := b.count // 2 = 4
-- 1) Split `a'.
a1 := new_sub_number (n + 1, a.count, a) = [227,26,41,95]
a2 := new_sub_number (1, n.max (1), a) = [169,93,135,110]
-- 2) Split `b'.
b1 := new_sub_number (n + 1, b.count, b) = [161,167,158,41]
b2 := new_sub_number (1, n.max (1), b) = [164,0,0,0]
-- 3b) Q = beta^n -1 and ...
--> q := ones (4) = [255,255,255,255] <-- Is this the error?
-- ... R1 = [A1,A2] - [B1,0] + [0,B1].
r1 := a + b1 = [227,26,41,96,75,5,37,151]
b1.shift_left (n) = [161,167,158,41,0,0,0,0]
r1.subtract (b1) = [65,114,139,55,75,5,37,151]
d := q * b2 = [163,255,255,255,92,0,0,0]
r1.shift_left (n) = [227,25,135,184,172,220,37,151,0,0,0,0] -- too big!
r := r1 + a3 - d -= [227,25,135,184,8,220,37,152,0,164,19,39] -- too big!
I know this is long, but any help is appreciated.
I would suggest to check that r1 = [65,114,139,55,75,5,37,151] is still the same before doing r1.shift_left (n). There are two options:
d := q * b2 affects r1 while it should not. Most probably there is some aliasing, i.e. r1 is aliased with some other variable that is updated and this aliasing should be removed.
r1 is still the same after d := q * b2. The issue is with shift_left that fails to (re)initialize some data or uses global data that it should not.
f1(1^n01^m) = 1^|m−n|
design a turing machine that computes the function (transition diagram)
how to keep track of the 0 in the middle?
I have tried to do it but can not figure it out
I'll assume you want the tape alphabet to consist only of 0, 1 and - (blank). Our strategy here is a fruitful one when working with single-tape Turing machines: we will bounce back and forth around the 0 in the middle, crossing off 1s as we find them. We will continue until we run out of 1s and reach a blank. At that point, all that remains on the tape is 1^|m-n| as well as n+m+1-|m-n| zeroes. Finally, we copy our result to the beginning of the tape (if that's not where it already is, i.e., if m > n) and erase the zeroes.
Q s s' D Q'
// read past 1^n
q0 1 1 R q0
// read through zeroes
q0 0 0 R q1
q1 0 0 R q1
// mark out the first 1 remaining in 1^m
q1 1 0 L q2
// read through zeros backwards
q2 0 0 L q2
// mark out the last 1 remaining in 1^n
q2 1 0 R q1
// we were reading through zeroes forward
// and didn't find another 1. n >= m and
// we have deleted the same number from
// the first and last parts so just delete
// zeroes
q1 - - L q3
q3 0 - L q3
q3 1 1 L halt_accept
// we were reading through zeroes backwards
// and didn't find another 1. n < m and we
// accidentally deleted one too many symbols
// from the 1^m part. write it back and start
// copying the 1s from after the 0s back to
// the beginning of the tape. then, clear zeroes.
q2 - - R q4
q4 0 1 R q5
q5 0 0 R q5
q5 1 0 L q6
q6 0 0 L q6
q6 1 1 R q4
q5 - - L q7
q7 0 - L q7
q7 1 1 L halt_accept
Naturally, no TM example would be complete without an example of its execution.
-111110111- => -111110111- => -111110111-
^ ^ ^
q0 q0 q0
=> -111110111- => -111110111- => -111110111-
^ ^ ^
q0 q0 q0
=> -111110111- => -111110011- => -111110011-
^ ^ ^
q1 q2 q2
=> -111100011- => -111100011- => -111100011-
^ ^ ^
q1 q1 q1
=> -111100001- => -111100001- => -111100001-
^ ^ ^
q2 q2 q2
=> -111100001- => -111000001- => -111000001-
^ ^ ^
q1 q1 q1
=> -111000001- => -111000001- => -111000001-
^ ^ ^
q1 q1 q1
=> -111000000- => -111000000- => -111000000-
^ ^ ^
q2 q2 q2
=> -111000000- => -111000000- => -111000000-
^ ^ ^
q2 q2 q2
=> -110000000- => -110000000- => -110000000-
^ ^ ^
q1 q1 q1
=> -110000000- => -110000000- => -110000000-
^ ^ ^
q1 q1 q1
=> -110000000- => -110000000- => -11000000--
^ ^ ^
q1 q3 q3
=> -1100000--- => -110000---- => -11000-----
^ ^ ^
q1 q3 q3
=> -1100------ => -110------- => -11--------
^ ^ ^
q1 q3 q3
=> -11--------
^
halt_accept
I have to translate the following vhdl program to verilog:
ENTITY ascounter IS
PORT (CLK :IN STD_LOGIC;
QoutA, QoutB, QoutC, QoutD :OUT STD_LOGIC);
END ascounter;
ARCHITECTURE circuit OF ascounter IS
SIGNAL CLKnot, QBnot, QCnot, QDnot, QA, QB, QC, QD, HIGH :STD_LOGIC;
BEGIN
HIGH<='1';
CLKnot<=NOT CLK;
QDnot<=NOT QD;
QCnot<=NOT QC;
QBnot<=NOT QB;
FFD: JKFF PORT MAP (J=>HIGH, K=>HIGH, CLK=>CLKnot, CLRN=>HIGH, PRN=>HIGH, Q=>QD);
FFC: JKFF PORT MAP (J=>HIGH, K=>HIGH, CLK=>QDnot, CLRN=>HIGH, PRN=>HIGH, Q=>QC);
FFB: JKFF PORT MAP (J=>HIGH, K=>HIGH, CLK=>QCnot, CLRN=>HIGH, PRN=>HIGH, Q=>QB);
FFA: JKFF PORT MAP (J=>HIGH, K=>HIGH, CLK=>QBnot, CLRN=>HIGH, PRN=>HIGH, Q=>QA);
QoutA<=QA;
QoutB<=QB;
QoutC<=QC;
QoutD<=QD;
END circuit;
and I have done it:
...
assign HIGH = 1'b1;
assign CLKnot = (~CLK);
assign QDnot = (~QD);
assign QCnot = (~QC);
assign QBnot = (~QB);
flipflop_jk FFD(.J(HIGH), .K(HIGH), .CK(CLKnot), .CLN(HIGH), .PRN(HIGH), .Q(QD));
flipflop_jk FFC(.J(HIGH), .K(HIGH), .CK(QDnot), .CLN(HIGH), .PRN(HIGH), .Q(QC));
flipflop_jk FFB(.J(HIGH), .K(HIGH), .CK(QCnot), .CLN(HIGH), .PRN(HIGH), .Q(QB));
flipflop_jk FFA(.J(HIGH), .K(HIGH), .CK(QBnot), .CLN(HIGH), .PRN(HIGH), .Q(QA));
assign QoutA = QA;
assign QoutB = QB;
assign QoutC = QC;
assign QoutD = QD;
I have used a jk flipflop:
always #(CK or PRN or CLN)
begin
if (PRN == 1'b0)
begin
Q <= 1'b1 ;
end
else if (CLN == 1'b0)
begin
Q <= 1'b0 ;
end
else if (CK == 1'b0)
begin
if (J == 1'b1 & K == 1'b1)
begin
Q <= ~Q ;
end
else if (J == 1'b1 & K == 1'b0)
begin
Q <= 1'b1 ;
end
else if (J == 1'b0 & K == 1'b1)
begin
Q <= 1'b0 ;
end
end
end
When I try to run the simulation, I get something like this which is wrong, but I cannot understand where the mistake is.
Does anyone have any idea?
Thank you very much!
It would be more appropriate to use edge sensitivity in the flipflop_jk definition, Also you have included an asynchronous clear signal, with a different value to your reset signal. My example shows this with a synchronous clear.
Your signal capture does not show your reset signal. I assume this is initially low then you take it high after time 0. To set Q to a known value.
module flipflop_jk(
input CK,
input PRN,
input CLN,
input J,
input K,
output reg Q
);
always #(posedge CK or negedge PRN) begin
if (PRN == 1'b0) begin
Q <= 1'b1 ;
end
else begin
if (CLN == 1'b0) begin
Q <= 1'b0 ;
end
else if (J == 1'b1 & K == 1'b1) begin
Q <= ~Q ;
end
else if (J == 1'b1 & K == 1'b0) begin
Q <= 1'b1 ;
end
else if (J == 1'b0 & K == 1'b1) begin
Q <= 1'b0 ;
end
end
end
endmodule
I assume you have declared Q as a reg in your jk flipflop module. By default in Verilog, a reg is initialized to x. Since the J, K, CLN and PRN inputs to your jk flipflop are tied high (1'b1), the only statement which is executed is Q <= ~Q ; (when CK goes low). Q remains unknown since the invert of x is still x. You never set Q to a known value.
Disclaimer: this is a question that requires some explanation of code and algorithm. It is not intended to fix anything or optimize anything but rather facilitate understanding.
My understanding of sorting routines is not great. I asked for help with converting an already available code for mergesort from integer type to string type here: delphi mergesort for string arrays. After I received my answer I set out to understand the sorting routine.
Couple of resources came handy to help understanding:
http://www.iti.fh-flensburg.de/lang/algorithmen/sortieren/merge/mergen.htm
http://www.youtube.com/watch?v=9Qk1t66g7IU
I attempted to dissect the code to follow it along. This question is not my attempt to validate my own understanding of mergesort, but rather show the sorting routine in a clear manner. The value of this question is for people attempting to understand mergesort better. This is essential as other sorts can be understood easier if you understand one prototype well.
My question is why did we add "1" to set length and to "Result"
SetLength(AVals, Length(Vals) div 2 + 1);
Result := 1 + PerformMergeSort(0, High(Vals));
and why did we subtract "1" here? EDIT: I think K will be out of bounds if not subtract 1?
Result := k - 1;
here is the code in this question; BTW this is an optimized mergesort as it copies only half the array:
function MergeSortRemoveDuplicates(var Vals: array of Integer):Integer;
var
AVals: array of Integer;
//returns index of the last valid element
function Merge(I0, I1, J0, J1: Integer):Integer;
var
i, j, k, LC:Integer;
begin
LC := I1 - I0;
for i := 0 to LC do
AVals[i]:=Vals[i + I0];
//copy lower half or Vals into temporary array AVals
k := I0;
i := 0;
j := J0;
while ((i <= LC) and (j <= J1)) do
if (AVals[i] < Vals[j]) then begin
Vals[k] := AVals[i];
inc(i);
inc(k);
end else if (AVals[i] > Vals[j]) then begin
Vals[k]:=Vals[j];
inc(k);
inc(j);
end else begin //duplicate
Vals[k] := AVals[i];
inc(i);
inc(j);
inc(k);
end;
//copy the rest
while i <= LC do begin
Vals[k] := AVals[i];
inc(i);
inc(k);
end;
if k <> j then
while j <= J1 do begin
Vals[k]:=Vals[j];
inc(k);
inc(j);
end;
Result := k - 1;
end;
//returns index of the last valid element
function PerformMergeSort(ALo, AHi:Integer): Integer; //returns
var
AMid, I1, J1:Integer;
begin
//It would be wise to use Insertion Sort when (AHi - ALo) is small (about 32-100)
if (ALo < AHi) then
begin
AMid:=(ALo + AHi) shr 1;
I1 := PerformMergeSort(ALo, AMid);
J1 := PerformMergeSort(AMid + 1, AHi);
Result := Merge(ALo, I1, AMid + 1, J1);
end else
Result := ALo;
end;
begin
SetLength(AVals, Length(Vals) div 2 + 1);
Result := 1 + PerformMergeSort(0, High(Vals));
end;
here is my understanding with very small modification:
function MergeSortRemoveDuplicates(var Vals: array of Integer):Integer;
var
AVals: array of Integer;
//returns index of the last valid element
function Merge(I0, I1, J0, J1: Integer):Integer;
var
i, j, k, LC:Integer;
begin
// difference between mid-point on leftside
// between low(Original_array) and midpoint(true Original_array midpoint)
// subtracting I0 which is Low(Original_array)
// or here equals zero(0)
// so LC is quarter point in Original_array??
LC := I1 - I0;
// here we walk from begining of array
// and copy the elements between zero and LC
// this is funny call that Vals[i + I0] like 0 + 0
// then 1 + 0 and so on. I guess this guarantees if we are
// starting from non-zero based array??
for i := 0 to LC do
AVals[i]:=Vals[i + I0];
// k equal low(Original_array)
k := I0;
// I will be our zero based counter element
i := 0;
// J will be (midpoint + 1) or
// begining element of right side of array
j := J0;
// while we look at Copy_array elements
// between first element (low(Copy_array)
// and original_array from midpoint + 1 to high(Original_array)
// we start to sort it
while ((i <= LC) and (j <= J1)) do
// if the value at Copy_array is smaller than the Original_array
// we move it to begining of Original_array
// remember position K is first element
if (AVals[i] < Vals[j]) then begin
Vals[k] := AVals[i];
// move to next element in Copy_array
inc(i);
// move to next element in Original_array
inc(k);
// if the value at copy_array is larger
// then we move smaller value from J Original_array (J is midpoint+1)
// to position K original_array (K now is the lower part of ) Original_array)
end else if (AVals[i] > Vals[j]) then begin
Vals[k]:=Vals[j];
//move K to the next element in Original_array
inc(k);
// move j to next element in Original_array
inc(j);
// if the value in Original_array is equal to the element in Copy_array
// do nothing and count everything up
// so we end up with one copy from duplicate and disregard the rest
end else begin //duplicate
Vals[k] := AVals[i];
inc(i);
inc(j);
inc(k);
end;
//copy the rest
while i <= LC do begin
Vals[k] := AVals[i];
inc(i);
inc(k);
end;
// if the counters do not endup at the same element
// this means we have some that maybe leftover on
// the right side of the Original_array.
// This explains why K does not equal J : there are still elements left over
// then copy them to Original_array
// starting at position K.
if k <> j then
while j <= J1 do begin
Vals[k]:=Vals[j];
inc(k);
inc(j);
end;
// why K - 1?
// function needs result so return will be null if called
// I don't understand this part
Result := k - 1;
end;
//returns index of the last valid element
function PerformMergeSort(ALo, AHi:Integer): Integer; //returns
var
AMid, I1, J1:Integer;
begin
//It would be wise to use Insertion Sort when (AHi - ALo) is small (about 32-100)
if (ALo < AHi) then
begin
AMid:=(ALo + AHi) shr 1; // midpoint
I1 := PerformMergeSort(ALo, AMid); //recursive call I1 is a data point on the left
J1 := PerformMergeSort(AMid + 1, AHi); // recursive call I1 is a data point on the right
Result := Merge(ALo, I1, AMid + 1, J1);
end else
Result := ALo;
end;
begin
// test if array is even then we can split nicely down middle
if Length(Vals) mod 2 = 0 then
begin
SetLength(AVals, Length(Vals) shr 1);
Result := PerformMergeSort(0, High(Vals));
end
else
//array is odd let us add 1 to it and make it even
// shr 1 is essentially dividing by 2 but doing it on the bit level
begin
SetLength(AVals, (Length(Vals) + 1) shr 1);
Result := PerformMergeSort(0, High(Vals));
end;
end;
This is my modification of code presented by author, intended to remove duplicates during the sorting. Some explanations:
External function:
We should provide buffer (AVals) to store half of the initial aray. Length(Vals) div 2 + 1 provides enough space for odd- and even-sized arrays without unnecessary complication. Better value (for all cases): Length(Vals + 1) div 2
Internal procedure PerformMergeSort returns index of the last valid element, but external procedure returns count of valid elements (it was commented in the cited topic), so I use (1 + PerformMergeSort()).
Reasons: internally we have to work with indexes, but end user of this procedure should know new array length.
Internal function PerformMergeSort:
It takes start and end indexes of array chunk, sorting this chunk and returns index of the last valid element. After recursive calls we have this situation.
Invariant: both chunks are sorted, they don't contain duplicates, non-zero length of left segment
*****ACDEFG****BCDEGHILM******
^ ^ ^ ^
| | | |
Alo I1 AMid+1 J1
I0 I1 J0 J1 //as named in Merge
\____/
LC+1 elements
And after merging:
*****ABCDEFGHILM**************
^ ^^
| ||__k
| |
Alo Result
Internal function Merge:
Use provided example, pen and paper, step through merging, see how it works.
Concerning to copy cycle: we copy (LC+1) elements to temporary buffer AVals, using start segment of AVals (always starting from 0) and proper segment of the main array (starting from I0, it is usually non-zero)
First off, I would like to state this is on a practice exam I am taking. I know the answers to be: cout = 4ns, and S = 7ns. Just looking for a little explanation. Thanks in advance.
For the VHDL implementation of a full adder shown below, when do the outputs cout and S settle at their final values (consider the worst case timing path with the worst case inputs)?
architecture concurrent_behavior of full_adder is
signal t1, t2, t3, t4, t5: std_logic;
begin
t1 <= not A after 1 ns;
t2 <= not cin after 1 ns;
t4 <= not ((A or cin) and B) after 2 ns;
t3 <= not ((t1 or t2) and (A or cin)) after 2 ns;
t5 <= t3 nand B after 2 ns;
S <= not((B or t3) and t5) after 2 ns;
cout <= not(t1 or t2) and t4) after 2 ns;
end concurrent_behavior;
You basically just trace through the dependencies, and add up the dependencies for each route through the logic. Normally it's easiest to trace backwards from an output to the inputs it needs. For example:
cout <= not(t1 or t2) and t4) after 2 ns;
So, the last stage for cout has a 2 ns delay. Its inputs are t1, t2 and t4, so its 2 ns delay can't start until t1, t2 and t4 are all ready (i.e., the single longest of those delays determines the start time for the last stage).
In this case, t1 and t2 are delayed by 1 ns apiece, and t4 is delayed by 2 ns. Therefore, the last stage starts 2 ns after the initial input. That gives 2+2 = 4 ns from initial input to final output.
Looking at it from an algorithmic viewpoint, we could state it that the delay for any signal is the delay of the final "stage" for that signal plus the maximum of the delays for any of its inputs.
For S:
total = 2 + max_delay(B, t3, t5)
total = 2 + delay(t5);
total = 2 + 2 + max_delay(t3, B)
total = 2 + 2 + delay(t3)
total = 2 + 2 + 2 + max_delay(t1, t2, A, cin)
total = 2 + 2 + 2 + delay(t1) (or delay(t2) -- they're the same).
total = 2 + 2 + 2 + 1