hexadecimal seven segment display verilog - verilog

I've taken a project using verilog. We have two 4-bits number, a multiplexer(S0,S1) and four module(adder,substractor,and,xor). Output is 4 bit. I think it seems simple alu. I have written a verilog code that contains all of them as modules. I have assigned pins to DE0 board. As you can see, the output can be seen on leds. There is no problem about that. But, how the output can be displayed on Seven Segment Display instead of LEDs? However, the result should be hexadecimal instead of binary. I have also pins about seven segment display, so I think I will implement them like the leds. I'm new about verilog. It will be my first program.
If S is 0 (00), adder result will be seen on LEDs.
If S is 1 (01), subtraction result will be seen on LEDs.
If S is 2 (10), AND operation result will be seen on LEDs.
If S is 3 (11), XOR operation result will be seen on LEDs.

A seven segment display is really just 7 LEDs in a figure 8 pattern (with a 8th LED for the decimal point). As such, you need only drive the pin attached to that segment of the display LOW to light up the segment (See the handbook on the DE0, Section 4.3, for the pins attached to the seven segment display: ftp://ftp.altera.com/up/pub/Altera_Material/Boards/DE0/DE0_User_Manual.pdf ). Now, this means you have control over each segment but just driving your 4 bit number into the display wont product something you can easily read. For this, youre going to need a converter from your 4bit value into a 7bit values representing the pattern to light the seven segment up (Ie, if your output is 4'b0001, you want your seven segment to display a 1, so you need to convert the 4'b0001 into a 7bit value that will result in a 1 being displayed). I think this is a worthy design challenge for you to take on as you learn Verilog, so I will not provide code for a 4-bit to seven segment display module. But if you run into any issues creating your own; feel free to comment to this answer and we can try and help. Or make a new question if its a big issue.

Related

Design a counter with a count sequence using Verilog

Design a counter with a count sequence based on your ID number as follows: write down your student ID, append two 0’s and then append your ID with each digit incremented modulo 10. For example if your student ID is 27273289, then the count sequence is 272732890038384390 and then back to the start. Implement your design with at most 5 flip-flops using Verilog on a DE2 board. Show the result on a 7 segment display using HEX. How do I go about this?
5 flip-flops implies 32 states. Your sequence 272732890038384390 is 19 long.
Build a state machine which counts from 0 to 18, looping back to 0 on completion.
Then use a look up table (combinatorial logic) to decode state into an output value.
Update question with code if you get stuck, then we can help with the programming problem.

Verilog: Converting BCD (or binary) to BCH

I'm looking to code a BCD (or binary) to binary-coded hexadecimal which will be then converted to 7-segment display codes and sent serially to a latched shift register to drive the display. It's for a 16-bit microprocessor, that outputs signed 16-bit number.
I've already successfully coded and fully tested a binary to BCD converter using the shift and add 3 algorithm. The number is converted to positive if negative and a sign flag is set to notate sign. Most design example I saw on the internet were combinatorial. I took a sequential approach to it, and takes around 35 clock cycles to do so.
My question is, is there a way to convert the BCD I have to BCH? Or perhaps it would be easier to convert the binary to BCH. Whichever way is more feasible. Performance is not an issue. Is there an existing algorithm to do so?
I appreciate your responses.
You should just use a look up table. Have an input to your case statement be your BCD digit, and the output be your BCH digit. Both will be 4 bits wide guaranteed, so you can parse your BCD digits one at a time and each one will produce a 4 bit output.
Converting from Binary to BCD is harder because you need to use a double dabble algorithm (as you have found out). But once it's in BCD you shouldn't have a problem going to BCH.

scale 14 bit word to an 8 bit word

I'm working on a project where I sample a signal with an ADC, that represents values as 14 bit words. I need to scale the values to 8 bit words. What's a good way to go about this in general. By the way, I'm using an FPGA so I'd like to do it in "hardware" rather than a software solution. Also in case you're wondering the chain of events will be: sample analog signal, represent sample value with 14 bit word, scale 14 bit word to 8 bit word, transmit 8 bit word with UART to PC COM1.
I've never done this before. I was assuming you use quantization levels, but I'm not sure what an efficient circuit for this operation would be. Any help would be appreciated.
Thanks
You just need an add and a shift:
val_8 = (val_14 + 32) >> 6;
(The + 32 is necessary to get correct rounding - you can omit it but you will get more truncation noise in your signal if you do.)
I think you just drop the six lowest resolution bits and call it good, right? But I might not fully understand the problem statement.
Paul's algorithm is correct, but you'll need some bounds checking.
assign val_8 = (&val_14[13:5]) ? //Make sure your sum won't overflow
8'hFF : //Assign all 1's if it will
val_14[13:6] + val_14[5];

Verilog array syntax

I'm new to Verilog, and am having a lot of trouble with it. For example, I want to have an array with eight cells, each of which is 8 bits wide. The following doesn't work:
reg [7:0] transitionTable [0:7];
assign transitionTable[0] = 10;
neither does just doing transitionTable[0] = 10; or transitionTable[0] = 8'h10; Any ideas?
(In case it is not obvious and relevant: I want to make a finite state machine, and specify the state transitions in an array, since that seems easier than a massive case switch.)
When using assign you should declare the array as a wire instead of areg.
Since your goal is to design an FSM, there is no need to store the state values in an array. This is typically done using Verilog parameter's, a state register and a next_state with a case/endcase statement.
The following paper shows a complete example: FSM Fundamentals
If this is targeted towards synthesis:
A little beyond what was answered above, there are standard FSM coding styles that you should adhere to so the tools can perform better optimization. As described in the Cummings paper, one-hot is usually best for FPGA devices and in fact ISE(with default settings) will ignore your encoding and implement whatever it thinks will best utilize the resources on the device. This almost invariably results in a one-hot encoded FSM regardless of the state encoding you chose, provided it recognizes your FSM.
OK, so to answer your question, let's dig a little deeper into Verilog syntax.
First of all, to specify a range of bits, either do [MSB:LSB] or [LSB:MSB]. The standard is MSB:LSB but it is really up to you here, but try to be consistent.
Next, in array instantiation we have:
reg WIDTH reg_name NUMBER;
where WIDTH is the "size" of each element and NUMBER is the number of elements in the array.
So, you first want to do:
reg [7:0] transitionTable [7:0];
Then, to assign particular bytes (8 bits = 1 byte), do:
initial begin
transitionTable[0] = 8'h10;
end
A good book to learn Verilog from is FPGA Prototyping By Verilog Examples by Pong P. Chu.

Multiplying 23 bit datatypes in a system with no long long

I am trying to implement floating point operations in a microcontroller and so far I have had ample success.
The problem lies in the way I do multiplication in my computer and it works fine:
unsigned long long gig,mm1,mm2;
unsigned long m,m1,m2;
mm1 = f1.float_parts.mantissa;
mm2 = f2.float_parts.mantissa;
m1 = f1.float_parts.mantissa;
m2 = f2.float_parts.mantissa;
gig = mm1*mm2; //this works fine I get all the bits I need since they are all long long, but won't work in the mcu
gig = m1*m2//this does not work, to be precise it gives only the 32 least significant bits , but works on the mcu
So you can see that my problem is that the microcontroller will throw an undefined refence to __muldi3 if I try the gig = mm1*mm2 there.
And If I try with the smaller data types, it only keeps the least significant bits, which I don't want it to. I need the 23 msb bits of the product.
Does anyone have any ideas as to how I can do this?
Apologizes for the short answer, I hope that someone else will take the time to write a fuller explanation, but basically you do exactly as when you multiply two big numbers by hand on a paper! It's just that instead of working with base 10, you work in base 256. That is, treat your numbers as a byte vectors, and do with each byte what you do to a digit when you "hand multiply".
The comments in the FreeBSD implementation of __muldi3() have a good explanation of the required procedure, see muldi3.c. If you want to go straight to the source (always a good idea!), according to the comments this code was based on an algorithm described in Knuth's The Art of Computer Programming vol. 2 (2nd ed), section 4.3.3, p. 278. (N.B. the link is for the 3rd edition.)
Back on the Intel 8088 (the original PC CPU and the last CPU I wrote assembly code for) when you multiplied two 16 bit numbers (32 bits? whoow) the CPU would return 2 16 bit numbers in two different registers - one with the 16 msb and one with the lsb.
You should check the hardware capabilities of your micro-controller, maybe it has a similar setup (obviously you'll need the code this in assembly if it does).
Otherwise you'll have to implement multiplication on your own.

Resources