I am working on a stopwatch and reaction timer in verilog. I have my stopwatch working, but I am having trouble with one part of the reaction timer. The goal is to hit a button, and a random amount of time later an led turns on and starts the timer, and you time yourself how long it takes you to stop the timer after the led turns on. Anyways, I have it so when I hit the reaction timer start button (when Cen == 2'b10), the timer starts counting. I am wondering how I can add a delay in between the button press and the timer starting. You can see right now when Cen == 2'b10, there is my attempt at a delay using the register "count," but it doesn't seem to work. I am just trying to do a fixed delay for now, then i'll implement the randomizer later, but the delay using my "count" method doesn't work. Any ideas? Let me know if you need any clarification. Thanks!
module Counter4dig(
input [1:0] Cen,
//input incIn,
input clk, rst, inc,
output reg[3:0] Dig0,
output reg[3:0] Dig1,
output reg[3:0] Dig2,
output reg[3:0] Dig3
);
reg ReactionCounter;
reg RandomValue;
reg [30:0] count = 1'b0;
always # (posedge(clk), posedge(rst))
begin
if (rst == 1'b1)begin
Dig0 <= 4'b0000;
Dig1 <= 4'b0000;
Dig2 <= 4'b0000;
Dig3 <= 4'b0000;
end
//increment if inc
else if(inc == 1'b1)
begin
Dig0 <= Dig0 + 1'b1;
if(Dig0 == 4'b1001)
begin
Dig0 <= 4'b0000;
//add 1 to second digit (when first resets) up till 9
Dig1 <= Dig1 + 1'b1;
end
//reset if == 10
if(Dig1 == 4'b1001 && Dig0 == 4'b1001)
begin
Dig1 <= 4'b0000;
//add 1 to third digit (when second reset) up till 9
Dig2 <= Dig2 + 1'b1;
end
//reset if == 10
if(Dig2 == 4'b1001 && Dig1 == 4'b1001 && Dig0 == 4'b1001)
begin
Dig2 <= 4'b0000;
//add 1 to fourth digit (when third reset) up till 9
Dig3 <= Dig3 + 1'b1;
end
//reset if == 10
if(Dig3 > 4'b1001)
begin
Dig3 <= 4'b0000;
end
end
else if (Cen == 2'b10)
begin
if (count != 50000)
count <= count + 1;
else
begin
Dig0 <= Dig0 + 1'b1;
if(Dig0 == 4'b1001)
begin
Dig0 <= 4'b0000;
//add 1 to second digit (when first resets) up till 9
Dig1 <= Dig1 + 1'b1;
end
//reset if == 10
if(Dig1 == 4'b1001 && Dig0 == 4'b1001)
begin
Dig1 <= 4'b0000;
//add 1 to third digit (when second reset) up till 9
Dig2 <= Dig2 + 1'b1;
end
//reset if == 10
if(Dig2 == 4'b1001 && Dig1 == 4'b1001 && Dig0 == 4'b1001)
begin
Dig2 <= 4'b0000;
//add 1 to fourth digit (when third reset) up till 9
Dig3 <= Dig3 + 1'b1;
end
//reset if == 10
if(Dig3 > 4'b1001)
begin
Dig3 <= 4'b0000;
end
end
end
//only continue if Cen is 01 & not inc
else if(Cen == 2'b01)
begin
//add 1 to first digit up till 9
Dig0 <= Dig0 + 1'b1;
//reset if == 10
if(Dig0 == 4'b1001)
begin
Dig0 <= 4'b0000;
//add 1 to second digit (when first resets) up till 9
Dig1 <= Dig1 + 1'b1;
end
//reset if == 10
if(Dig1 == 4'b1010)
begin
Dig1 <= 4'b0000;
//add 1 to third digit (when second reset) up till 9
Dig2 <= Dig2 + 1'b1;
end
//reset if == 10
if(Dig2 == 4'b1010)
begin
Dig2 <= 4'b0000;
//add 1 to fourth digit (when third reset) up till 9
Dig3 <= Dig3 + 1'b1;
end
//reset if == 10
if(Dig3 > 4'b1001)
begin
Dig3 <= 4'b0000;
end
end
//end
end
endmodule
You assign the reg [30:0] count = 1'b0; First of all, you are only assigning one bit, instead of 31 bits. Use 31'b0. Next, you are assigning count outside of an always statement with a blocking assignment and then inside the statement with a non-blocking assignment. I am not sure this is synthesizeable.
Would it be fair to say that you need the counter to reset to zero right as the button press occurs and then starting counting? Assuming that it would continue counting while the button was still pressed, you might try this.
reg[1:0] Cen_d; // Used to capture the Cen for use in a making a pulse
reg Cen_pulse;
generator
always # (posedge clk)
begin
Cen_d <= Cen; // capture the old Cen value
Cen_pulse <= Cen == 2'b10 & (Cen != Cen_d); // Look for Cen == 2'b01 and
// the old Cen (in Cen_d) is
// is not current Cen. If so
// pulse once.
end
always # (posedge clk or posedge reset)
begin
if (reset)
count <= 31'h0000_0000;
else
begin
count = Cen_pulse ? 31'h0000_0000 : // Return to zero on pulse
count >= 50000 ? 31'd500000 : // Stop counting at 50000
count = count + 1; // Otherwise increment
end
end
Related
So I have seen something like the code below in a React-Redux application
return StartTime <= currentTime && currentTime <= EndTime;
What exactly does this line returns to? What does the <= mean?
This is "less than or equal to" operator.
Example:
return 3 <= 3 && 4 <= 5 //true&&true - true
return 3 <= 2 && 4 <= 5 //false&&true - false
It's the less than or equal to operator.
1 <= 2 // true
1 <= 1 // true
1 <= 0 // false
I am using 50MHz clock in fpga and trying make 5 seconds timer. below cnt_t reach to 5 x 50MHz (x"0EE6B280" --> 250,000,000) then make time_tick_32 to 1 and make cnt_t <= x"00000000";. The code below did not work never time_tick_32 gets 1.
signal cnt_t : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";
signal time_tick : STD_LOGIC:= '0' ;
signal time_tick_32 : STD_LOGIC_VECTOR(31 DOWNTO 0):= x"00000000";
process (clk_50) IS
begin
if falling_edge(clk_50) then
cnt_t <= cnt_t + '1';
end if;
if (cnt_t = x"0EE6B280") then --if 5 seconds
time_tick <= '1';
cnt_t <= x"00000000";
time_tick_32(0)<=time_tick;
else
time_tick <= '0';
time_tick_32(0)<=time_tick;
end if;
end process;
Try:
signal cnt_t : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";
signal time_tick : STD_LOGIC:= '0' ;
signal time_tick_32 : STD_LOGIC_VECTOR(31 DOWNTO 0):= x"00000000";
-- I assume you begin your architecture somewhere
-- Can make the following a concurrent statement
-- (unless it is some kind of shift reg assigned in a diff process...
-- then you will get multiple driver issues)
time_tick_32(0) <= time_tick;
process (clk_50) IS
begin
if rising_edge(clk_50) then -- Changed to rising_edge;
-- Any particular reason you are using falling_edge?
if (cnt_t = x"0EE6B280") then --if 5 seconds
time_tick <= '1';
cnt_t <= x"00000000";
else
time_tick <= '0';
cnt_t <= cnt_t + '1';
end if;
end if;
end process;
I am stuck trying to figure this out. I have an array:
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1]
I want to add the values in the array so that it equal to 10. Once the added value reaches 10, I want the array to start adding the value again until it reaches 10. There is two problem that I face here,
1) How can I add the array so that the sum = 10 everytime. Notice that in the array, there is 3. If I add all the value before 3, I get 8 and I only need 2 from 3. I need to make sure that the remainder, which is 1 is added to the next array to get the sum 10.
2) How do I break the loop once it reaches 10 and ask it continue the summation to next value to get another 10?
I created a loop but it only works for the first part of the array. I have no idea how to make it continue. The code is as follow:
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1];
c = 0;
for i = 1:length(a)
while c < 10
c = c + a(i);
break
end
end
Please help. Thank you
This can be done using cumsum, mod, diff and find as follows:
temp = cumsum(a);
required = find([0 diff(mod(temp,10))] <0)
cumsum returns the cumulative sum which then is rescaled using mod. diff determines where the sum gets greater than or equal to 10 and finally find determines those indexes.
Edit: Above solution works if a doesn't have negative elements. If a can have negative elements then:
temp1=cumsum(a); %Commulative Sum
temp2=[0 diff(mod(temp1,10))];%Indexes where sum >=10 (indicated by negative values)
temp2(temp1<0)=0; %Removing false indexes which may come if `a` has -ve values
required = find(temp2 <0) %Required indexes
This should do what you are trying. It displays the index at which each time the sum equals 10. Check this with your testcases. rem stores the residual sum in each iteration which is carried forward in the next iteration. The rest of the code is similar to what you were doing.
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1];
c = 0;
rem = 0;
i = 1;
length(a);
while(i <= length(a))
c = rem;
while (c < 10 && i <= length(a))
c = c + a(i);
i = i + 1;
if(c >= 10)
rem = c - 10;
break
end
end
if(c >= 10)
disp(i-1)
end
use cumsum instead of your while loop:
a = [ 1 1 1 2 1 1 1 3 2 1 1 2 1 1 1];
a_ = a;
endidxlist = false(size(a));
startidxlist = false(size(a));
startidxlist(1) = true;
while any(a_) && (sum(a_) >= 10)
b = cumsum(a_);
idx = find(b >= 10,1);
endidxlist(idx) = true;
% move residual to the next sequence
a_(idx) = b(idx) - 10;
if a_(idx) > 0
startidxlist(idx) = idx;
elseif (idx+1) <= numel(a)
startidxlist(idx+1) = true;
end
a_(1:idx-1) = 0;
end
if (idx+1) <= numel(a)
startidxlist(idx+1) = false;
end
endidxlist gives you the end-indexes of each sequence and startidxlist the start-indexes
I want make a one second timer with atmega8 and timer0. I used 8Mhz crystal and prescale = 1.
Every 125ns timer0 increases by one, so when timer0 overflows 31250 times, we should have one second, but it doesn't work properly and delays more then 5 seconds.
I used BascomAVR.
$regfile = "m8def.dat"
$crystal = 8000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6
,Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Timer0 = Timer , Prescale = 1
Dim Second As Word , Minute As Word , Hour As Word , Z As Integer
Second = 0
Minute = 0
Hour = 0
Z = 0
Enable Interrupts
Enable Timer0
Enable Ovf0
On Ovf0 Ovfroutin
Timer0 = 0
Start Timer0
Cursor Off
Cls : Home
Lcd "00:00:00"
Do
Loop
End 'end program
Ovfroutin:
Incr Z
If Z = 31250 Then
Stop Timer0
Z = 0
Incr Second
If Second = 60 Then
Second = 0
Incr Minute
If Minute = 60 Then
Minute = 0
Incr Hour
If Hour = 24 Then
Hour = 0
End If
If Hour < 10 Then
Locate 1 , 1
Lcd "0"
Locate 1 , 2
Else
Locate 1 , 1
End If
Lcd Hour
End If
If Minute < 10 Then
Locate 1 , 4
Lcd "0"
Locate 1 , 5
Else
Locate 1 , 4
End If
Lcd Minute
End If
If Second < 10 Then
Locate 1 , 7
Lcd "0"
Locate 1 , 8
Else
Locate 1 , 7
End If
Lcd Second
Start Timer0
End If
Timer0 = 0
Return
I'm trying to make brick break in VHDL.
Everything went well but I have a weird problem.
In a piece of my code you see below I change the value to '0' at index (y,x) in my array when the ball reaches the edges of a brick. The problem is that all the values in my array change to 0, even when the ball is not moving (When the program start up, the ball is not moving).
process(Ball_x1,Ball_x2,Ball_y1,Ball_y2) begin
x1 <= 280 + (x * 55); --edges of my brick
x2 <= 280 + ((x + 1) * 55);
y1 <= 108 + (y * 13);
y2 <= 108 + ((y + 1) * 13);
waardeArray := level1(y,x);
if (vcnt >= y1) and (vcnt <= y2) then
if (Ball_x1 >= x1) and (Ball_x1 <= x2) then -- edges of my ball
if waardeArray = '1' then
level1(y,x) := '0';
end if;
end if;
end if;
end process;
The declaration of my array is
type levels is array ( 0 to 3, 0 to 5 ) of bit;
shared variable level1 : levels := (
('1','0','0','0','0','1'),
('0','1','0','0','1','0'),
('0','0','1','1','0','0'),
('0','0','1','1','0','0')
);
Next variable is used to store the value of the array at place (y,x)
shared variable waardeArray: bit;
It's the intention to use Ball_x2 etc too but I just tried with 1 edge of my ball to test the code.
Update
process(Ball_x1,Ball_x2,Ball_y1,Ball_y2) begin
x1 <= 280 + (x * 55); -- edges of my brick
x2 <= 280 + ((x + 1) * 55);
y1 <= 108 + (y * 13);
y2 <= 108 + ((y + 1) * 13);
if (vcnt >= y1) and (vcnt <= y2) then --vcnt is from another component where I send my data to my screen
if (Ball_x1 >= x1) and (Ball_x1 <= x2) then -- left edge of my ball
if level1(y)(x) = '1' then
level1(y)(x) <= '1'; --I do this to test if the elements with value 1 stay 1 and the 0 stay 0 ata initialization, but every element in my array change to 1.
else
level1(y)(x) <= level1(y)(x);
end if;
end if;
end if;
end process;
Declarations
signal x: integer range 0 to 6 := 0; --Six is used for something else.
signal y: integer range 0 to 3 := 0;
signal x1: integer range 279 to 616;
signal x2: integer range 279 to 616;
signal y1: integer range 107 to 228;
signal y2: integer range 107 to 228;
signal color: std_logic_vector (7 downto 0) := "00000111";
type levels is array ( 0 to 3) of std_logic_vector (5 downto 0);
signal level1 : levels := ("101101",
"010010",
"001100",
"001100");
This is my intention
Don't use shared variables. If you need to communicate a value between processes, use a signal. You can't be sure of the order at which updates compared to reads occur using shared variables. Well, you can, but you have to use protected types.
Also, in your process, you are looking at the values of x, y and vcnt. But those signals (I hope they are signals not shared variables :) are not in the sensitivity list of the process, so when they change, your process will not be triggered.