Good afternoon people, i'm trying to code in Verilog a structure than can store up to 64 different 8bit numbers (64X8), which is only allowed to store numbers greater than 125 and bellow or equal to 250. When it is writing (or not), it can show the maximum current stored value (VAL_MAX) as well as it's position (POS_MAX). When not writing (EN_WR ==0) i simply put in POS_RD the position that i want, in order to see what number is stored there, and when the memory is full (NR_ST = 64) it replaces the oldest stored numbers with the new ones, one by one. I currently have the code but there are some issues:
1st - When the memory is full and for eg. i have 250 in the 2nd position, the output will be
VAL_MAX= 250 ; POS_MAX=1. When a bunch of new numbers come, that maximum should be replaced with the 2nd highest stored value and must show it's position, but the memory isn't showing a new Max Value.
2nd - When i want to see the number stored in the 1st position (POS_RD = 0) the output VAL_RD (used to read the stored numbers) is "X" and not the stored number, i don't know if it is saving or not.
The code is:
module Bloco(VAL_SENSOR, EN_WR, POS_RD, NR_ST, VAL_MAX, POS_MAX, VAL_RD, segundo, clk);
parameter MEM_SIZE = 64;
parameter MEM_WIDTH = 8;
parameter ADDR_SIZE = 5;
input[MEM_WIDTH - 1:0] VAL_SENSOR;
input[5:0] POS_RD;
input EN_WR,segundo,clk;
output[6:0] NR_ST;
output[MEM_WIDTH - 1:0] VAL_MAX;
output[ADDR_SIZE :0]POS_MAX;
output[MEM_WIDTH - 1:0]VAL_RD;
reg[MEM_WIDTH - 1:0] ram[MEM_SIZE - 1:0]; // C , L
reg[MEM_WIDTH - 1:0] VAL_RD;
reg[MEM_WIDTH - 1:0] val_max = 0; //necessita de variavel so por causa do valor inicial
reg[ADDR_SIZE :0] POS_MAX = 0;
reg[ADDR_SIZE :0] POS_MAX2 = 0;
reg[ADDR_SIZE + 1:0] NR_ST_COUNTER = 0; //addr_size + 1 because it needs to count from zero to the number of values
reg[ADDR_SIZE :0] POS_POINTER = 0;
assign VAL_MAX = val_max;
assign NR_ST = NR_ST_COUNTER;
always # (posedge clk)
begin
if(EN_WR) //Caso esteja habilitado o sistema de armazenamento
begin
if(segundo)
begin
if(VAL_SENSOR > 125 && VAL_SENSOR <= 250) //Se for um numero abaixo de 250 unid. luminosas e acima de 125
begin //Escrita
if(POS_POINTER == POS_MAX)
POS_MAX <= POS_MAX2;
else
ram[POS_POINTER] <= VAL_SENSOR;
if(NR_ST_COUNTER < 64) //atualizar Contador de Valores guardados
NR_ST_COUNTER = NR_ST_COUNTER + 1;
if(VAL_SENSOR > val_max) //atualizar MAX
begin
POS_MAX <= POS_POINTER;
val_max <= VAL_SENSOR;
end
else //ver se encaixa no segundo maior POS_MAX2
begin
if(VAL_SENSOR > ram[POS_MAX2]) //nao precisa guardar o valor
POS_MAX2 <= POS_POINTER;
end
POS_POINTER <= POS_POINTER + 1;
end
end
end
else
VAL_RD <= ram[POS_RD];
end
endmodule
.
NOTE = The input "segundo" is like EN_WR, but it's only used after 10 clock cycles (it will be linked to a Counter).
Thank you.
To answer your questions:
1) The reason you are likely not seeing the second highest value in your memory appear on VAL_MAX when the current max is overridden is because you never change val_max register to contain the value of ram[POS_MAX2], ie the second highest value. However, as you do not have an ordered data structure and do not store any more than the second highest value (and do not search the memory for the second highest value), you cannot reliably keep finding the next highest value when the current highest is removed/overridden. You might need to rethink alot of how you are doing this if you need to always have the current highest value in the memory being output on VAL_MAX.
2) Position 0 is not being written to the first time you write to the memory; thus you are getting the default value of the memory, ie 'x. Here way:
if(POS_POINTER == POS_MAX)
POS_MAX <= POS_MAX2;
else
ram[POS_POINTER] <= VAL_SENSOR;
In the above lines, you only put values in the memory if the current position is not equal to the position of the current highest value. The first time you write (ie, to position 0), POS_POINTER and POS_MAX are at their initial values of 0, thus equal. So, ram[0] never gets updated as it is only executed if POS_POINTER and POS_MAX are not equal (which in this case, they are equal). If you were to write to position 0 a second time, you might be able to write to it as the value of POS_MAX might have changed. Note also, that you sometimes update the write pointer POS_POINTER even if you dont write there, as in the example above (even through ram[0] wasnt written to, you will still update POS_PONTER to be 1).
As mentioned in #1, depending on your requirements, you might not have the right structures here to meet them. If you always need to have the highest value in the memory output on VAL_MAX and always have the old value ejected, you might need to make old of those operations do a search, or store and update all the needed meta data.
Related
I have some questions regarding the flash memory with a dspic33ep512mu810.
I'm aware of how it should be done:
set all the register for address, latches, etc. Then do the sequence to start the write procedure or call the builtins function.
But I find that there is some small difference between what I'm experiencing and what is in the DOC.
when writing the flash in WORD mode. In the DOC it is pretty straightforward. Following is the example code in the DOC
int varWord1L = 0xXXXX;
int varWord1H = 0x00XX;
int varWord2L = 0xXXXX;
int varWord2H = 0x00XX;
int TargetWriteAddressL; // bits<15:0>
int TargetWriteAddressH; // bits<22:16>
NVMCON = 0x4001; // Set WREN and word program mode
TBLPAG = 0xFA; // write latch upper address
NVMADR = TargetWriteAddressL; // set target write address
NVMADRU = TargetWriteAddressH;
__builtin_tblwtl(0,varWord1L); // load write latches
__builtin_tblwth(0,varWord1H);
__builtin_tblwtl(0x2,varWord2L);
__builtin_tblwth(0x2,varWord2H);
__builtin_disi(5); // Disable interrupts for NVM unlock sequence
__builtin_write_NVM(); // initiate write
while(NVMCONbits.WR == 1);
But that code doesn't work depending on the address where I want to write. I found a fix to write one WORD but I can't write 2 WORD where I want. I store everything in the aux memory so the upper address(NVMADRU) is always 0x7F for me. The NVMADR is the address I can change. What I'm seeing is that if the address where I want to write modulo 4 is not 0 then I have to put my value in the 2 last latches, otherwise I have to put the value in the first latches.
If address modulo 4 is not zero, it doesn't work like the doc code(above). The value that will be at the address will be what is in the second set of latches.
I fixed it for writing only one word at a time like this:
if(Address % 4)
{
__builtin_tblwtl(0, 0xFFFF);
__builtin_tblwth(0, 0x00FF);
__builtin_tblwtl(2, ValueL);
__builtin_tblwth(2, ValueH);
}
else
{
__builtin_tblwtl(0, ValueL);
__builtin_tblwth(0, ValueH);
__builtin_tblwtl(2, 0xFFFF);
__builtin_tblwth(2, 0x00FF);
}
I want to know why I'm seeing this behavior?
2)I also want to write a full row.
That also doesn't seem to work for me and I don't know why because I'm doing what is in the DOC.
I tried a simple write row code and at the end I just read back the first 3 or 4 element that I wrote to see if it works:
NVMCON = 0x4002; //set for row programming
TBLPAG = 0x00FA; //set address for the write latches
NVMADRU = 0x007F; //upper address of the aux memory
NVMADR = 0xE7FA;
int latchoffset;
latchoffset = 0;
__builtin_tblwtl(latchoffset, 0);
__builtin_tblwth(latchoffset, 0); //current = 0, available = 1
latchoffset+=2;
__builtin_tblwtl(latchoffset, 1);
__builtin_tblwth(latchoffset, 1); //current = 0, available = 1
latchoffset+=2;
.
. all the way to 127(I know I could have done it in a loop)
.
__builtin_tblwtl(latchoffset, 127);
__builtin_tblwth(latchoffset, 127);
INTCON2bits.GIE = 0; //stop interrupt
__builtin_write_NVM();
while(NVMCONbits.WR == 1);
INTCON2bits.GIE = 1; //start interrupt
int testaddress;
testaddress = 0xE7FA;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
testaddress += 2;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
testaddress += 2;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
testaddress += 2;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
What I see is that the value that is stored in the address 0xE7FA is 125, in 0xE7FC is 126 and in 0xE7FE is 127. And the rest are all 0xFFFF.
Why is it taking only the last 3 latches and write them in the first 3 address?
Thanks in advance for your help people.
The dsPIC33 program memory space is treated as 24 bits wide, it is
more appropriate to think of each address of the program memory as a
lower and upper word, with the upper byte of the upper word being
unimplemented
(dsPIC33EPXXX datasheet)
There is a phantom byte every two program words.
Your code
if(Address % 4)
{
__builtin_tblwtl(0, 0xFFFF);
__builtin_tblwth(0, 0x00FF);
__builtin_tblwtl(2, ValueL);
__builtin_tblwth(2, ValueH);
}
else
{
__builtin_tblwtl(0, ValueL);
__builtin_tblwth(0, ValueH);
__builtin_tblwtl(2, 0xFFFF);
__builtin_tblwth(2, 0x00FF);
}
...will be fine for writing a bootloader if generating values from a valid Intel HEX file, but doesn't make it simple for storing data structures because the phantom byte is not taken into account.
If you create a uint32_t variable and look at the compiled HEX file, you'll notice that it in fact uses up the least significant words of two 24-bit program words. I.e. the 32-bit value is placed into a 64-bit range but only 48-bits out of the 64-bits are programmable, the others are phantom bytes (or zeros). Leaving three bytes per address modulo of 4 that are actually programmable.
What I tend to do if writing data is to keep everything 32-bit aligned and do the same as the compiler does.
Writing:
UINT32 value = ....;
:
__builtin_tblwtl(0, value.word.word_L); // least significant word of 32-bit value placed here
__builtin_tblwth(0, 0x00); // phantom byte + unused byte
__builtin_tblwtl(2, value.word.word_H); // most significant word of 32-bit value placed here
__builtin_tblwth(2, 0x00); // phantom byte + unused byte
Reading:
UINT32 *value
:
value->word.word_L = __builtin_tblrdl(offset);
value->word.word_H = __builtin_tblrdl(offset+2);
UINT32 structure:
typedef union _UINT32 {
uint32_t val32;
struct {
uint16_t word_L;
uint16_t word_H;
} word;
uint8_t bytes[4];
} UINT32;
My program uses alot of memory and Processing power, I can only search up to 6000, is there any way to reduce the amount of memory this uses? This will really help with future programming endevours as it will be nice to know how to work with memory smartly.
ArrayList<Integer> factor = new ArrayList<Integer>();
ArrayList<Integer> non = new ArrayList<Integer>();
ArrayList<Integer> prime = new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
System.out.println("Please enter how high we want to search");
long startTime = System.nanoTime();
int max = sc.nextInt();
int number = 2;
while (number < max)
{
for (int i=0;i<prime.size();i++)
{
int value = prime.get(i);
if (number % value == 0)
{
factor.add(value);
}
else
{
non.add(value);
}
}
if(factor.isEmpty())
{
prime.add(number);
}
else
{
composite.add(number);
}
factor.clear();
number++;
}
int howMany=prime.size();
System.out.printf("The are "+howMany+" prime numbers up to " +max + " and they are: " +prime );
System.out.println();
}
You do not say what language you are using, so this answer will be general.
To store primes up to 6,000 you only need about 3,000 bits which is less than 380 bytes. Your basic solution is the Sieve of Eratosthenes and the fact that 2 is the only even prime. You set up the sieve to handle only odd numbers, which halves the storage needed. Since the sieve only holds prime or not prime for each odd number, the storage can be reduced to a single bit for each number.
Once you have set up your sieve, there are many sites including this one which have instructions in different languages, you just need to retrieve the prime/not prime value from the sieve for the numbers in your range. Here is the pseudocode for checking if a number is prime, assuming the sieve has already been set up:
boolean function isPrime(number)
// Low numbers
if (number < 2)
return false
endif
// Even numbers
if (number is even)
return number == 2
endif
// Odd numbers >= 3
return sieve[(number - 1) / 2] == 1
end function
Low numbers are not prime. 2 is the only even prime; all other even numbers are not prime. The prime flag for the odd number 2n+1 is stored at bit n in the sieve. This assumes that the language you are using allows bit level access, something like a BitSet in Java.
I have a logic problem for an iOS app but I don't want to solve it using brute-force.
I have a set of integers, the values are not unique:
[3,4,1,7,1,2,5,6,3,4........]
How can I get a subset from it with these 3 conditions:
I can only pick a defined amount of values.
The sum of the picked elements are equal to a value.
The selection must be random, so if there's more than one solution to the value, it will not always return the same.
Thanks in advance!
This is the subset sum problem, it is a known NP-Complete problem, and thus there is no known efficient (polynomial) solution to it.
However, if you are dealing with only relatively low integers - there is a pseudo polynomial time solution using Dynamic Programming.
The idea is to build a matrix bottom-up that follows the next recursive formulas:
D(x,i) = false x<0
D(0,i) = true
D(x,0) = false x != 0
D(x,i) = D(x,i-1) OR D(x-arr[i],i-1)
The idea is to mimic an exhaustive search - at each point you "guess" if the element is chosen or not.
To get the actual subset, you need to trace back your matrix. You iterate from D(SUM,n), (assuming the value is true) - you do the following (after the matrix is already filled up):
if D(x-arr[i-1],i-1) == true:
add arr[i] to the set
modify x <- x - arr[i-1]
modify i <- i-1
else // that means D(x,i-1) must be true
just modify i <- i-1
To get a random subset at each time, if both D(x-arr[i-1],i-1) == true AND D(x,i-1) == true choose randomly which course of action to take.
Python Code (If you don't know python read it as pseudo-code, it is very easy to follow).
arr = [1,2,4,5]
n = len(arr)
SUM = 6
#pre processing:
D = [[True] * (n+1)]
for x in range(1,SUM+1):
D.append([False]*(n+1))
#DP solution to populate D:
for x in range(1,SUM+1):
for i in range(1,n+1):
D[x][i] = D[x][i-1]
if x >= arr[i-1]:
D[x][i] = D[x][i] or D[x-arr[i-1]][i-1]
print D
#get a random solution:
if D[SUM][n] == False:
print 'no solution'
else:
sol = []
x = SUM
i = n
while x != 0:
possibleVals = []
if D[x][i-1] == True:
possibleVals.append(x)
if x >= arr[i-1] and D[x-arr[i-1]][i-1] == True:
possibleVals.append(x-arr[i-1])
#by here possibleVals contains 1/2 solutions, depending on how many choices we have.
#chose randomly one of them
from random import randint
r = possibleVals[randint(0,len(possibleVals)-1)]
#if decided to add element:
if r != x:
sol.append(x-r)
#modify i and x accordingly
x = r
i = i-1
print sol
P.S.
The above give you random choice, but NOT with uniform distribution of the permutations.
To achieve uniform distribution, you need to count the number of possible choices to build each number.
The formulas will be:
D(x,i) = 0 x<0
D(0,i) = 1
D(x,0) = 0 x != 0
D(x,i) = D(x,i-1) + D(x-arr[i],i-1)
And when generating the permutation, you do the same logic, but you decide to add the element i in probability D(x-arr[i],i-1) / D(x,i)
I'm writing a game using Corona SDK in lua language. I'm having a hard time coming up with a logic for a system like this;
I have different items. I want some items to have 1/1000 chance of being chosen (a unique item), I want some to have 1/10, some 2/10 etc.
I was thinking of populating a table and picking a random item. For example I'd add 100 of "X" item to the table and than 1 "Y" item. So by choosing randomly from [0,101] I kind of achieve what I want but I was wondering if there were any other ways of doing it.
items = {
Cat = { probability = 100/1000 }, -- i.e. 1/10
Dog = { probability = 200/1000 }, -- i.e. 2/10
Ant = { probability = 699/1000 },
Unicorn = { probability = 1/1000 },
}
function getRandomItem()
local p = math.random()
local cumulativeProbability = 0
for name, item in pairs(items) do
cumulativeProbability = cumulativeProbability + item.probability
if p <= cumulativeProbability then
return name, item
end
end
end
You want the probabilities to add up to 1. So if you increase the probability of an item (or add an item), you'll want to subtract from other items. That's why I wrote 1/10 as 100/1000: it's easier to see how things are distributed and to update them when you have a common denominator.
You can confirm you're getting the distribution you expect like this:
local count = { }
local iterations = 1000000
for i=1,iterations do
local name = getRandomItem()
count[name] = (count[name] or 0) + 1
end
for name, count in pairs(count) do
print(name, count/iterations)
end
I believe this answer is a lot easier to work with - albeit slightly slower in execution.
local chancesTbl = {
-- You can fill these with any non-negative integer you want
-- No need to make sure they sum up to anything specific
["a"] = 2,
["b"] = 1,
["c"] = 3
}
local function GetWeightedRandomKey()
local sum = 0
for _, chance in pairs(chancesTbl) do
sum = sum + chance
end
local rand = math.random(sum)
local winningKey
for key, chance in pairs(chancesTbl) do
winningKey = key
rand = rand - chance
if rand <= 0 then break end
end
return winningKey
end
I'm learning SQL using SQLAnywhere which I believe uses a fairly standard SQL syntax
My problem is I have created a table MatchRecord with an Id as char(4) NOT NULL, a score as decimal and a pins as decimal.
now I want to create a procedure insert_scores to insert values into the table
I have got so far as :
create procedure insert_scores(IN play_id char(4), IN play_score decimal(5, 2),
IN no_pins decimal(5, 2), OUT a_message varchar(40))
begin
if substr(play_id, 1, 1)in (Upper('M','F', 'J'
then
if isnumeric(substr(play_id 2, 3)) = 1
then
if isnumeric(play_score) = 1
then
if isnumeric(no_pins) = 1
then
insert into MatchRecord(id, score, pins)
values(play_id, play_score, no_pins);
set a_message = 'Entry successful';
else
set a_message = 'Number of pins must be decimal ie, 1.6 ';
end if;
else
set a_message = 'Score must be decimal ie, 9.4 ';
end if;
else
set a_message = 'ID number must be in range 000 to 999 ';
end if;
else
set a_message = 'First character of ID must be M, F of J':
end if;
end
this works fine apart for any accidental insertion of a character in either of the decimal values, whereupon the system throws an error, it seems to check the table type before it reads the if statement,
I have tried isnumeric(string(play_score)) = 1 but still the same error.
Is there any way of checking that the number passed in play_score and no_pins is a decimal before the first if statement?
You could try to transform your number into a string and then check if there is a dot in the string. Something like this could do the trick.
DECLARE #number_is_ok BIT
SET #number_is_ok = CASE charindex('.', CAST(play_score as CHAR))
WHEN 0 THEN 0
ELSE 1
END
You could do then a simple check if the number is decimal or not and then continue with the corresponding logic.
IF #number_is_ok = 1 ...