How to display a 14 bit output onto a 2 digit display? - hardware

I have a analogue to digital converter that after conversion stores its results in two 14 bit registers. I have to display this value onto a 2 digit 7 segment display.
Here is the simulation showing the 14 bit result:
As can be seen the values are quite large for a 2 digit display. I can display these values to a one tenth of a volt. Here is the display multiplexing circuit:
module muxer(
input clock,
input reset,
input [3:0] second,
input [3:0] first,
output a_m,
output b_m,
output c_m,
output d_m,
output e_m,
output f_m,
output g_m,
output [1:0] cat_m
);
//The Circuit for 7 Segment Multiplexing -
localparam N = 18;
reg [N-1:0]count; //the 18 bit counter which allows us to multiplex at 1000Hz
always # (posedge clock)
begin
if (reset)
count <= 0;
else
count <= count + 1;
end
reg [3:0]sseg; //the 4 bit register to hold the data that is to be output
reg [1:0]cat_temp; //register for the 2 bit enable
always # (*)
begin
case(count[N-1:N-2]) //MSB and MSB-1 for multiplexing
2'b00 :
begin
sseg = first;
cat_temp = 2'b01;
end
2'b01:
begin
sseg = second;
cat_temp = 2'b10;
end
endcase
end
assign cat_m = cat_temp;
reg [6:0] sseg_temp;
always # (*)
begin
case(sseg)
4'd0 : sseg_temp = 7'b1000000; //display 0
4'd1 : sseg_temp = 7'b1111001; //display 1
4'd2 : sseg_temp = 7'b0100100; //display 2
4'd3 : sseg_temp = 7'b0110000; //display 3
4'd4 : sseg_temp = 7'b0011001; //display 4
4'd5 : sseg_temp = 7'b0010010; //display 5
4'd6 : sseg_temp = 7'b0000010; //display 6
4'd7 : sseg_temp = 7'b1111000; //display 7
4'd8 : sseg_temp = 7'b0000000; //display 8
4'd9 : sseg_temp = 7'b0010000; //display 9
default : sseg_temp = 7'b0111111; //dash
endcase
end
assign {g_m, f_m, e_m, d_m, c_m, b_m, a_m} = sseg_temp;
endmodule
I have made it so that I can display the digits by passing the values to the first and second register. but dont know how to accomplish this with the values of DataA and DataB shown in simulation.
Thanks

Well, you can do this no problem. It's just that you won't be displaying 'digits' on the seven segment display in the sense of them being recognizable numbers in decimal or hex. Each of the segments can represent a bit. You have seven segments per 'digit' and 2 'digits'. 7 * 2 = 14.

You could scroll the 5 digits you have across the two physical digits displayed. It might be quite unpleasant to read though.

Related

Arduino LCD 2 digits to 1 digit

I have a problem with showing numbers on the LCD screen in Tinkercad. The time is counting down from 60 seconds. But when it counts until 9-1 the number has shown as 90-10. Eg: LCD screen shows 20 at 2 seconds instead of 02 or 2 only. May I know how can I change it to only 1 digit or 09-01? Hope someone can help me with this. Thanks in advance.
Here my code for Arduino of LCD:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
lcd.begin(16, 2); // Set up the number of columns and rows on the LCD.
// Print a message to the LCD.
lcd.print("Ambulance is approaching!");
}
void loop()
{
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting
// begins with 0):
lcd.setCursor(0,1);
// Print a message to the LCD.
lcd.print("Time:");
for (int seconds = 60; seconds > 0; --seconds){
lcd.setCursor(6,1);
lcd.print(seconds-1);
delay(1000);
}
}
This is because lcd.print only overwrites the necessary characters. So after displaying 11 it overwrites it with a 10 correctly. After that it overwrites the 1 with a 9 and the 0 stays because the new input is only one character long.
You can clear the line by printing a string containing two spaces and then print the time.
for (int seconds = 60; seconds > 0; --seconds){
lcd.setCursor(6,1);
lcd.print(" ");
lcd.setCursor(6,1);
lcd.print(seconds-1);
delay(1000);
}

Specman - add bits in the beginning and end of list of bit

I have the following list of bit which contains 8 bits (input to function):
bs: list of bit;
I have the following struct:
struct uart_frame_s like any_sequence_item {
%start_bit : bit;
data_size : uint;
%data[data_size] : list of bit;
%stop_bit : bit;
keep soft start_bit == 0;
keep soft stop_bit == 1;
keep soft data_size == 8;
};
I have to execute the following:
unpack(packing.low, bs, current_frame);
The problem that bs size is 8, but current frame contains 10 bits....
So how can I add bits in the beginning and end of list of bit ('0' in the beginning and '1' in the end).
Or alternatively verify that the bs will unpack to 1-8 bits in current frame.
if you want to pack the bs into the frame data field, you can -
unpack(packing.low, bs, current_frame.data);

I wrote a verilog code but got errors like not a constant or unknown type

How can I remove the errors mentioned in the title?
reg [3:0]count;
reg [6:0]seg;
always # (posedge clock) begin
if (reset)
count = 0;
else
count = count+1'b0; //starting A counter
end
begin // this seems to need an "always #*" just before "begin"
case(count)
4'b0000: seg = 7'b0000001;
endcase
end
assign {a,b,c,d,e,f,g} = seg;
endmodule // where is "module"?
It shows error 44 i.e. count is not a constant
Error 1059 i.e. seg is of unknown type. Please help.
can't figure out what to do next
This seems to be a 7-segment counter that displays an hexadecimal value based on the value of a running 4-bit counter.
First, you need to declare inputs and outputs of your module, which can be done (in Verilog 2001) as this:
module counter7seg (
input wire clock,
input wire reset,
output wire a,
output wire b,
output wire c,
output wire d,
output wire e,
output wire f,
output wire g
);
This part of your description looks almost fine: a 4 bit counter. But you need (as Morgan pointed) to fix two things: assignments within a clocked always must be nonblocking ( <= instead of = ), and your counter, to be able to count, must add 1, not 0:
always # (posedge clock) begin
if (reset)
count <= 0;
else
count <= count+1'b1; //starting A counter
end
The following part, when you take the value of count and derive values for the segments, is incomplete: you need 16 cases here.
I can see that you use negative logic to switch on segments, so effectively, 0000 becomes 0000001, 0001 becomes (just guessing by the contents of picture below) 1001111,.... 1000 becomes 0000000, and so on.
always #* begin
case(count) // 16 cases here + default
4'b0000: seg = 7'b0000001; // 0
4'b0001: seg = 7'b1001111; // 1
4'b0010: seg = 7'b0110110; // 2
//......
//......
4'b1000: seg = 7'b0000000; // 8
//......
//......
4'b1111: seg = 7'b0110000; // a nice capital F
default: seg = 7'b1111111; // a default case with all segments off
endcase
end

Data is not picked up from instantiated outputs

I have instantiated a stopwatch module into this multiplexer module. The stopwatch is working as it is supposed to and is producing the expected output. This is also picked up by the instantiated registers. But, if I want to use this data further down the module, it does not work.
Here is the simulation showing my problem:
The values picked up from the stopwatch module are working perfectly. These values are then transferred to the registers regd0, regd1, regd2, regd3 which, instead of displaying the values are displaying 0?
Here is the code that produced the above simulation:
module muxer(
input clock,
input reset,
input [1:0] select,
output a,
output b,
output c,
output d,
output e,
output f,
output g,
output dp,
output [3:0] an
);
reg go_hi, go_start;
wire[3:0] wire_d0, wire_d1, wire_d2, wire_d3; // timer registers that will hold the individual counts
wire[3:0] wire_hd0, wire_hd1, wire_hd2, wire_hd3; //regsiters to hold the "hi" values
reg [3:0] regd0, regd1, regd2, regd3; //registers for LED multiplexing
//instantiate the "hi" module
say_hi sayhi(.clock(clock), .reset(reset), .go(go_hi), .hi_d0(wire_hd0), .hi_d1(wire_hd1), .hi_d2(wire_hd2), .hi_d3(wire_hd3)) ;
//instantiate the stopwatch module
stopwatch timer(.clock(clock), .reset(reset), .start(go_start), .d0(wire_d0), .d1(wire_d1), .d2(wire_d2), .d3(wire_d3) );
always # (select)
begin
case(select)
00: //hi
begin
go_start = 0; //make sure timer module is off
go_hi = 1'b1; //enable go signal to display "hi"
regd0 = wire_hd0; //transfer values to the multiplexing circuit
regd1 = wire_hd1;
regd2 = wire_hd2;
regd3 = wire_hd3;
end
01: //timer
begin
go_hi = 0; //make sure "hi" module is off
go_start = 1'b1; //enable start signal to start timer
regd0 = wire_d0;
regd1 = wire_d1;
regd2 = wire_d2;
regd3 = wire_d3;
end
10: //stop timer
begin
go_hi = 0;
go_start = 1'b0;
end
endcase
end
//The Circuit for 7 Segment Multiplexing -
localparam N = 8; //18 for implementation, 8 for simulation
reg [N-1:0]count;
always # (posedge clock or posedge reset)
begin
if (reset)
count <= 0;
else
count <= count + 1;
end
reg [6:0]sseg;
reg [3:0]an_temp;
reg reg_dp;
always # (*)
begin
case(count[N-1:N-2])
2'b00 :
begin
sseg = regd0;
an_temp = 4'b1110;
reg_dp = 1'b1;
end
2'b01:
begin
sseg = regd1;
an_temp = 4'b1101;
reg_dp = 1'b0;
end
2'b10:
begin
sseg = regd2;
an_temp = 4'b1011;
reg_dp = 1'b1;
end
2'b11:
begin
sseg = regd3;
an_temp = 4'b0111;
reg_dp = 1'b0;
end
endcase
end
assign an = an_temp;
reg [6:0] sseg_temp;
always # (*)
begin
case(sseg)
4'd0 : sseg_temp = 7'b1000000; //display 0
4'd1 : sseg_temp = 7'b1111001; //display 1
4'd2 : sseg_temp = 7'b0100100;// display 2
4'd3 : sseg_temp = 7'b0110000;
4'd4 : sseg_temp = 7'b0011001;
4'd5 : sseg_temp = 7'b0010010;
4'd6 : sseg_temp = 7'b0000010;
4'd7 : sseg_temp = 7'b1111000;
4'd8 : sseg_temp = 7'b0000000;
4'd9 : sseg_temp = 7'b0010000;
4'd10 : sseg_temp = 7'b0001001; //to display H
4'd11 : sseg_temp = 7'b0000111; //to display I
default : sseg_temp = 7'b0111111; //dash
endcase
end
assign {g, f, e, d, c, b, a} = sseg_temp;
assign dp = reg_dp;
endmodule
My guess is that select does not equal 01. You should show that in waves as well.
Here are a couple of other observations.
If you want regd0 to model combinational logic, you should change always #(select) to always #*. Same for d1-d3. Currently, I think you are modeling latches.
In your case statement 10 refers to decimal 10. You probably wanted 2'b10.

How to interchange the position of each of my four ui-elements randomly? - algorithm for the 24 possibilities

I have a program with four different buttons. I want to interchange the position of the buttons randomly. For example: 1 2 3 4 Later: 3 4 1 2 Later: 1 3 2 4
Is there a algorithms for that? The only way I can think is to make a random number from 1 to 24 (24 possibilities) and then code all the possible button postitions.
int foo = arcrandom() % 23;
switch(foo){
case 0:
button1postiton = 100; //just an example
button2position = 200;
button3position = 300;
button4position = 400;
break;
case 2:
button1postiton = 200;
//blablabla and so on and so on
}
But is there a more efficient way?
Thanks!
You could shuffle the buttons or their positions, e.g. with a Fisher-Yates shuffle.
There is code in this website to get a list of all permutations of an array (see method perm2), it is coded for char arrays, but can be modified to do int arrays as well and to other languages as well, then you can use mjv's idea.
http://www.cs.princeton.edu/introcs/23recursion/Permutations.java.html
If in Java, this is what I would try....
Once you get all the possible permutations maybe in a vector, I think you can use a grid bag layout and change the grid constraints, picking one of the elements of the vector randomly. I have not tried this out, but I am thinking along the lines of
Vector permutations = ... //get the permutation using a class similar to the one in the website for an array of ints {0,1,2,3}
//The panel
JPanel pane;
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//Choose one permutation at random
int foo = arcrandom() % 23;
int current[] = permutations.get(foo);
//Add the buttons in the chosen order
button = new JButton("Button 1");
c.gridx = current[0];
c.gridy = 0;
pane.add(button, c);
button = new JButton("Button 2");
c.gridx = current[1];
c.gridy = 0;
pane.add(button, c);
button = new JButton("Button 3");
c.gridx = current[2];
c.gridy = 0;
pane.add(button, c);
button = new JButton("Button 4");
c.gridx = current[3];
c.gridy = 0;
pane.add(button, c);
Let me know if this works!
Start with a random number 0 <= r < 24
Start with your first position. Derive rr = r % 4 and r = r / 4. Those are the remainder and quotient respectively after division by 4.
The remainder specifies a position. Swap position 0 with the specified position.
For the next position, derive rr = r % 3 and r = r / 3. Again the remainder specifies a position, this time 0, 1 or 2, but relative to your current position (1).
Swap position 1 with position rr+1.
For the next position, derive rr = r % 2 and r = r / 2. Again the remainder specifies a position, this time 0 or 1, and relative to your current position again (2).
Swap position 2 with position rr+2.
For position 3, there is nothing to do.
Note - for each swap, one possibility is to swap a position with itself. Obviously no swap is needed for that.
This is probably the Fisher-Yates shuffle - I had no idea it had a name until today.
Thanks for all your answers! I used the Fisher-Yates shuffle! I found here a nice tutorial, how to use the algorithm in Objective-C: gorbster.net