VHDL Tutorial
VHDL Tutorial
be website: emsys.denayer.wenk.be
Projectleader Projectassistants
: :
Copyright (c) 2003 by Patrick Pelgrims, Tom Tierens, Dries Driessens and Philip Van Pelt. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/).
Page 1 of 127
I. Introduction
Traditionally, digital logic was implemented using the classic TTL-logic, a collection of digital functions (ports, counters, ...).
Figure 1: TTL NAND port Figure 1 gives an example of a NAND TTL port with the corresponding DIP-package. More complex systems can be designed by combining these basic structures. To illustrate this, an XOR function is implemented using AND, OR and NOT ports. TTL logic contains XOR- functions and the design is therefore only intended as an example. It is also possible to design an XOR by only using 4 NAND gates. A
A
0 0 1 1
B
0 1 0 1
Out
0 1 1 0
Out
As the complexity of designs grew, these methods became inadequate. The large amount of ICs together with the difficult routing and placement on the PCB made development and testing too complex. The first attempts to overcome these problems were to integrate a basic programmable structure into one Integrated Circuit (IC). This building block could now replace several classic TTLcomponents, thus reducing IC count. A Programmable Array Logic (or PAL) consists of a programmable ROM with added logic capacity (see Figure 3).
Page 2 of 127
Figure 3: PAL schematic These devices were an enormous success. Instead of having a separate IC for each function, there now was one component that could be programmed to behave as any other TTL module. Figure 4 illustrates the XOR function implemented on a PAL.
Because of the fixed topology, designs were limited to a few gates. Techniques evolved and the next generation of programmable hardware is called FPGA.
Page 3 of 127
II. FPGA
FPGAs (Field Programmable Gate Array) are devices that contain lots of building blocks (ports, logic, ) with a complete interconnection structure (see Figure 5a). By programming these connections, different logical blocks or slices can be linked to obtain the desired circuit.
(a)
(b)
(c) Figure 5: (a) Xilinx FPGA structure (b) Altera FPGA structure (c) Programmable interconnections (Xilinx) (d) I/O block (Altera Stratix)
(d)
Page 4 of 127
Figures 6 and 7 give an example of a logical element (LE) and a Configurable Logic Block (CLB). A LE or CLB consists out of three parts: a Look-Up Table (LUT), a Flip-flop (FF) and a multiplexer (MUX). The LUT is similar to the PAL structure. It is the combinatorial part of the cell and describes the function of that element, just like a truth table that maps the input to the output. Therefore the table can behave as any function: F=f(F1,F2,F3,F4) with Fi being the inputs and F the output. If needed, the LUT can also be used as fast RAM. A FF latches the data to be able to work synchronously. Finally the MUX will send the data to the appropriate line where it can be used by the next LE, CLB or block. The MUX maps the outputs of the LUT to the different output lines. A 4-bit signal selects 16 possible LUT outputs. An FPGA uses different kinds of lines to transport signals across the device. Each LE or CLB is connected to its neighbours with direct lines. This assures fast communication to combine several LEs or CLBs together. Longer lines connect clusters of LEs or CLBs, whereas long lines run over the complete FPGA. Together with the programmable interconnections (see Figure 5c) and the programmable I/O blocks, a complete design can be developed using only one programmable digital IC. The two major vendors of programmable logic are Altera and Xilinx. Each uses different approaches and will therefore be discussed next to each other.
Page 5 of 127
Configurable Logic Block (CLB) with 2 slices of a Xilinx Spartan Figure 7: CLB overview The advantages of using these techniques over a classical TTL-based system are speed and adaptability. When an error is made or a system upgrade is ready, reprogramming the device is sufficient to alter the system. Thus, cutting down design time. The automatic syntheses, easy testability and in-system logic analysers shorten this even more. On the other hand, the same device can perform different tasks according to the configuration downloaded into it (this can even be done on board without removing the component). Due to the increased complexity of FPGAs, it is possible to implement more complex and demanding structures and even integrate a complete design on one chip. The difference with e.g. a microprocessor is that the logic can execute in parallel. In a microprocessor all instructions are performed one after the other. The software gives the sequence of instructions that will execute. When comparing to a normal processor, FPGAs can perform better. The parallelism allows for more efficient computation. If the latter can carry out 100 instructions at the same time, the clock can be 100 times slower without losing any execution speed. An FPGA running at 50MHz can therefore be faster than a processor running at 500MHz, depending on the application. All this is possible by the large amount of transistors available in FPGAs. Programming these devices isnt easy. Each Look-Up Table (LUT), I/O block and interconnection needs to be programmed. This is the price you pay for flexibility. Luckily a programming language and tools were developed to make this a less complex task. The hardware isnt programmed bit by bit, but described in a high-level description language. By describing the behaviour, design can be completed in a shorter period and the code will be more readable and portable than a schematic entry.
Page 6 of 127
III.
VHDL language
VHDL is an acronym that stands for VHSIC Hardware Description Language. VHSIC is yet another acronym meaning Very High Speed Integrated Circuits. It can be used to describe, simulate, synthesize and document any digital electronic circuit. By downloading a configuration into an FPGA, a physical system is obtained. This system will be a combination of different logical elements (AND-, OR-ports, ...) and other digital structures (Memory, ...). Because this language is an international standard, it is independent of the FPGA manufacturer. The same code can be compiled for different ICs of different vendors. The final implementations may be different, but the functional properties will be the same for all devices. Notice that VHDL is not a programming language but a descriptive language. You always have to keep the hardware in mind. Think in hardware, not software. There are some alternatives to VHDL, of which VERILOG and ABEL are the most important ones. Building blocks are the basic structures of the VHDL language. The top-level block is composed of different building blocks. Each sub-block can also be composed of other blocks (see Figure 8).
Block A
Block B
Block C
Block D
Block F
Each block consists of two parts: an entity and an architecture element (see Figure 9). The entity describes the interface to that block and a separate part, the architecture, associated with the entity describes how that block operates. The entity is like a pin description in a data book, specifying the inputs and outputs to the block. The architecture can be compared to a schematic for the block, describing in words (not symbols) what the block does.
Page 7 of 127
VHDL file Entity declaration Architecture declaration Figure 9: VHDL-file structure This is illustrated in the following example: Figure 10a is the interface of a building block. Only the in-and outputs are given. The block itself is a black box. What it does is described by the architecture. If you want to design a XOR function, the architecture will be: C<=A xor B (cfr. C=A xor B). The VHDL code representing this block is given in figure 10b. entity XORport is port ( A,B: in BIT; C: out BIT ); end XORport; Architecture architecture dataflow of XORport is begin C<=A xor B; end dataflow; (b) Figure 10: (a) Interface (b) Architecture structure
Entity
A B
(a)
In the XORport entity declaration, A and B are declared as input bits, whereas C is declared as output bit. The architecture describes what the box will do; in this case the dataflow architecture uses the XORport entity and describes the behaviour of a XOR-port. A signal assignment statement describes how data flows from the signals on the right side of the <= operator to the signal on the left side.
Note: the <= symbol was chosen carefully to avoid confusion with the variable assignment operator (usually =) of typical programming languages. The signal assignment operator in VHDL specifies a relationship between signals, not a transfer of data as in most programming languages.
Evaluating the expression is performed by substituting the values of the signals in the expression and computing the result of each operator in the expression. The implementation of this XOR port is indicated in the next figures (see Figures 11 and 12). The first image gives a complete overview of the FPGA, whereas the next ones represent a zoomed in portion of the complete design. The second figure shows clearly the two input pins and the output pin. The logical unit is depicted in the last figure. Figure 13 shows the XORport-entity compiled by the Xilinx tool chain. Compare this to the schematic you would have expected to see.
Page 8 of 127
(a)
(b)
(c) Figure 12: XOR implementation on Xilinx Spartan (a) Overview (b) Routing (c) CLB overview
Page 9 of 127
When analysing the code in figure 10b, a syntax for writing VHDL code can be derived (see figure 14a and 14b).
Entity
Architecture
entity entity-name is architecture architecture-name of entity-name is variable declarations port ( signal declarations signal-names : mode signal-type; constant declarations signal-names : mode signal-type; function definitions component declarations signal-names : mode signal-type); end entity-name; begin concurrent-statement; concurrent-statement; end architecture-name; (a) (b) Figure 14: (a) Overview of entity (b) Architecture syntax
Different signal-types are given in figure 15. Because the bit-types are not always satisfactory, its best to use the std_logic-types. They can describe the status of a signal/pin more accurately (e.g. low, high, high impedance, dont care, ).
Signal-type
Signal-mode
bit (1 or 0) in bit_vector (combination of bits) out boolean (true or false) buffer integer (-231+1 to +231-1) inout real user-defined types (defined by libraries) std_logic std_logic_vector Figure 15: Overview of signal-types and signal-modes Page 10 of 127
Signals are the wires of VHDL. They are used to connect different blocks. Syntax: signal signal-names : signal-type Variable declarations Same as signals, but no physical significance. Syntax: variable variable-names : variable-type Constant declarations Fixed numbers can de declared constant to improve readability Syntax: constant constant-names : constant-type := constant-value Functions have the same meaning in VHDL as in most programming Function definitions languages. They can be used to define subroutines. Definitions of the components (blocks) you want to use in your Component design. declarations Figure 16: Overview of architecture declarations
Signal declarations
There are three ways to write an architecture: dataflow, behavioural and structural. These three will become clear while completing this course. In short, the dataflow structure will assign signals to certain outputs, given the inputs. This is done completely in parallel. Sometimes it is easier to write the code in a behavioural way. This means that different classic statements, like if-then-else, can be used. It will be executed sequential, thus one line after the other. The structural method is used to add the blocks described above to your architecture. A design can combine these different techniques. In this way each part of the code can be written in the most optimal approach. But more about this is explained later. Lets start by actually making our first design.
Page 11 of 127
IV.
First design
IMPORTANT:
Before powering up your development board or downloading a design, check everything and ask the instructor for confirmation. Make sure you are using the correct wall adaptor and be careful with lingering metal pieces or wires.
Design an application to let the GPIO LEDs (general purpose input/output LED) react to the buttons.
First the general design flow (see Figure 18) is illustrated. A step-by-step tutorial for both programming an Altera and a Xilinx device is worked out below. In the two designs, similar steps can be extracted:
Page 12 of 127
(a)
(b) Figure 18: (a) Altera design flow (b) Xilinx design flow
Page 13 of 127
A) ALTERA (Quartus)
1. Create a new project
First close any existing projects (Quartus automatically loads the last project used). File -> New Project Wizard Enter the filename and project name: E.g.: Filename: c:\qdesigns\laboVHDL Project name: exercise1 Press Next No need to add extra files to project Press Next Press Next Choose the family and type of FPGA (Stratix: EP1S10F780C6ES, Cyclone: EP1C20F400C7). Press Next Press Finish
Page 14 of 127
The first two lines indicate which library to use. Normally the standard logic library (std_logic) is used. It consists of a more complete set of states to correctly represent internal behaviour. From now on, only use these types (std_logic and std_logic_vector). Possible includes are: IEEE.STD_LOGIC_1164.ALL => adding basic std_logic functions IEEE.STD_LOGIC_ARITH.ALL => adding arrhythmic functions IEEE.STD_LOGIC_UNSIGNED.ALL => adding unsigned arrhythmic functions IEEE.STD_LOGIC_SIGNED.ALL => adding signed arrhythmic functions The suffix ALL indicates that all functions of that library are included. The entity consists of 4 inputs (buttons) and 4 outputs (LEDs). A single input for each button can be assigned, but it is easier to define them together (see Figure 19 & 20) as an array of input pins. This will make the design much more readable. Notice the definition of the size of our input vector (n-1 downto 0). This method can be used to access any part of the array. E.g.: sw(2) sw(3 downto 2)
entity button_to_led is port ( sw1 : IN std_logic; sw2 : IN std_logic; sw3 : IN std_logic; sw4 : IN std_logic; ledout1 : OUT std_logic; ledout2 : OUT std_logic; ledout3 : OUT std_logic; ledout4 : OUT std_logic ); end button_to_led; Figure 20: Button_to_led entity code without using vectors
The architecture is quite straightforward: send the status of the sw-vector to the ledout-vector. A little more explanation is needed, though. This is the dataflow-structure discussed earlier. Every line written after the begin-statement executes in parallel. This means that the code written, wont execute one step after the other. All is done simultaneously. The results of the calculations therefore arent available until the next update cycle is reached. You can look at the code as one big loop, starting with the BEGIN-statement until the END-statement. The signals are never updated inside the loop, only at the end. The next example (see Figure 21) illustrates this. Assume that a is defined as INOUT (multidirectional pin). architecture button_to_led_arch of button_to_led is begin a <= b; c <= a; end button_to_led_arch; Figure 21: Example of dataflow-structure
Page 15 of 127
Intuitively, after execution a, b and c should have the same value. Because these processes work in parallel, this is not true. The signal a is only changed at the end of the file. So assume that a=1, b=2 and c=3 before execution. At first, one would expect a to hold the value of b after the first statement. Then the next line would send this value to c. At the end a would equal b and c (a=b=c=2). But is not the case at all. Actually the two statements are executed at the same time. So when c <= a is carried out, the new value of a isnt available yet and therefore the old value is used. The signal a gets the old value of b and the signal c gets the old value of a. After one cycle, the result will be: a=2, b=2 and c=1. When all signals are updated, a new cycle starts. The next time step will result in the following values: a=2, b=2, c=2.
4. Analyse design
Before continuing the design, the synthesis tool needs to analyse the code written and checks it for the correct syntax. Processing -> Start -> Start analysis and synthesis If the code has no syntactical errors, everything should work fine. Otherwise some debugging needs to be done (more about that later).
5. Assign pins
If the desired circuit is implemented on a physical device, the design must to be mapped on the available programmable component by assigning signals to the pins of the FPGA. The integrated design environment needs to know how to allocate the signals to the available pins. Here you define which pin corresponds with which signal in your design. In appendix A an overview of the pins used in this tutorial can be found. For this design only the Button and the LED pins are of importance. See schematics in appendix E for more details. The easiest way is to use the pin assigner, but it is also possible to adapt the assignment in notepad. Start the pin assigner: Assignments -> Assign pins For each pin select the corresponding number and press the ...- button next to the pin name field. Press start and select the pin name you want to assign to this physical pin. Press > and OK E.g.: w5 => sw[0] Press add Repeat this until all pins are assigned. After assigning all pins press OK
IMPORTANT:
Before exiting the Settings menu. Press the Device & pin options button. Go to the Unused pins tab and select As inputs, tri-stated. We protect the hardware to define unused pins as input. This way we are sure not to cause short-circuits. Internally a pull-up resistor is foreseen to prevent the pin from oscillating. When you forget to do this, your design wont work.
Press ok
Page 16 of 127
Page 17 of 127
B) XILINX (ISE)
1. Create a new project
First close any existing projects (ISE automatically loads the last project used). File -> New Project Enter the project name and project location: E.g.: Filename: c:\xdesigns\laboVHDL Project name: exercise1 Press Next Choose the family and type of FPGA (Spartan2E: xc2s200e pq208 6, Spartan3: xc3s200 ft256). Choose following settings: Top-level Module Type: HDL Synthesis tool: XST Simulator: other Generated simulation language: VHDL Press Next Press Next Press Finish
Page 18 of 127
The first two lines indicate which library to use. Normally the standard logic library (std_logic) is used. It consists of a more complete set of states to correctly represent internal behaviour. From now on, only use these types (std_logic and std_logic_vector). Possible includes are: IEEE.STD_LOGIC_1164.ALL => adding basic std_logic functions IEEE.STD_LOGIC_ARITH.ALL => adding arrhythmic functions IEEE.STD_LOGIC_UNSIGNED.ALL => adding unsigned arrhythmic functions IEEE.STD_LOGIC_SIGNED.ALL => adding signed arrhythmic functions The suffix ALL indicates that all functions of that library are included. The entity consists of 4 inputs (buttons) and 4 outputs (LEDs). A single input for each button can be assigned, but it is easier to define them together (see Figure 22 & 23) as an array of input pins. This will make the design much more readable. Notice the definition of the size of our input vector (n-1 downto 0). This method can be used to access any part of the array. E.g.: sw(2) sw(3 downto 2)
entity button_to_led is port ( sw1 : IN std_logic; sw2 : IN std_logic; sw3 : IN std_logic; sw4 : IN std_logic; ledout1 : OUT std_logic; ledout2 : OUT std_logic; ledout3 : OUT std_logic; ledout4 : OUT std_logic ); end button_to_led; Figure 23: Button_to_led entity code without using vectors The architecture is quite straightforward: send the status of the sw-vector to the ledout-vector. A little more explanation is needed, though. This is the dataflow-structure discussed earlier. Every line written after the begin-statement executes in parallel. This means that the code written, wont execute one step after the other. All is done simultaneously. The results of the calculations therefore arent available until the next update cycle is reached. You can look at the code as one big loop, starting with the BEGIN-statement until the END-statement. The signals are never updated inside the loop, only at the end. The next example (see Figure 24) illustrates this. Assume that a is defined as INOUT (multidirectional pin).
architecture button_to_led_arch of button_to_led is begin a <= b; c <= a; end button_to_led_arch; Figure 24: Example of dataflow-structure
Page 19 of 127
Intuitively, after execution a, b and c should have the same value. Because these processes work in parallel, this is not true. The signal a is only changed at the end of the file. So assume that a=1, b=2 and c=3 before execution. At first, one would expect a to hold the value of b after the first statement. Then the next line would send this value to c. At the end a would equal b and c (a=b=c=2). But is not the case at all. Actually the two statements are executed at the same time. So when c <= a is carried out, the new value of a isnt available yet and therefore the old value is used. The signal a gets the old value of b and the signal c gets the old value of a. After one cycle, the result will be: a=2, b=2 and c=1. When all signals are updated, a new cycle starts. The next time step will result in the following values: a=2, b=2, c=2.
4. Assign pins
If the desired circuit needs to be implemented on a physical device, the design needs to be mapped on the available programmable component by assigning signals to the pins of the FPGA. The integrated design environment needs to know how to allocate the signals to the available pins. Here you define which pin corresponds with which signal in your design. In appendix A an overview of the pins used in this tutorial can be found. For this design only the Button and the LED pins are of importance. See schematics in appendix E for more details. Select the top-entity in the Sources in Project-list. Right click and select New Source. Select User Document and enter the filename (<top-entity>.ucf) For each pin write the following line of code: NET "<pin-name>" LOC = "<pin-location>"; E.g.: NET "button" LOC = "P40"; NET "sw<0>" LOC = "P16";
Page 20 of 127
Page 21 of 127
V. Exercises
All schematics and code can be found in appendix D. For more information consult these files.
This problem can be solved using Karnaugh-cards. The result will be like: A <= { [ b(0) and b(2) ] or [ b(2) and b(1) and b(0)] }; Remember that the buttons are inverted (active low). Assign the correct pins and test the application on the board. Board schematics can be found in appendix E.
Page 22 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity decode7segment is port ( code : IN std_logic_vector (3 downto 0); seg7 : OUT std_logic_vector (6 downto 0) ); end decode7segment; architecture dec7seg_arch of decode7segment is begin process(code) begin case code is when "0000" => seg7(6 downto 0) <= "1000000"; when "0001" => seg7(6 downto 0) <= "1111001"; ... when others => seg7(6 downto 0) <= "1111111"; end case; end process; end dec7seg_arch; Figure 26: 7-segment decoder using behavioural architecture
All code, written in the behavioural way must be included in the process tags. Next to this tag, the processs starting condition is defined. In this case this block of code should be executed each time the code parameter changes (process(code)). Within this block, different sequential lines of code can be written. For the 7-segment decoder a case is used. The parameter code is evaluated. If it equals 0000 set seg7 to "1000000". If it equals 0001 to "1111001". Board schematics can be found in appendix E.
Page 23 of 127
process(signal-names) begin -- sequential code: e.g.: case (signal-name) is when condition => action1; ... when others => action2; end case; if (condition) then action1; elsif (condition) then action2; ... else action3; end if; for variable/signal-name in start-value to stop-value loop action; end loop; end process;
Figure 27: Overview behavioural architecture
Page 24 of 127
process(clk) begin if (clk'EVENT and clk='1') then COUNTER action; end if; end process; (a) (b) Figure 28: (a) counter schematic (b) rising edge detection
4-bit Output
Notice that after the if-statement, no more else or elsif-statements are possible. It looks strange but when you keep the hardware in mind its obvious. A rising edge can be detected but what is a not rising edge? (A falling edge?, No edge?, ...)
Hint: define an internal signal that represents the state of the counter.
The counter and the 7-segment decoder are two VHDL blocks (and files) that need to be put together to visualise the counter. This will be done using the third and last method that can be used to describe hardware in VHDL: the structural method. This powerful technique allows programmers to combine different blocks and build a design from pre-defined structures. Make a new VHDL-file that will contain the actual top-entity for our counter. The design should look like figure 29.
--component declarations component entity-name port (signal-names : mode signal-type); end component;
Clock 7-segment Out 7
(a)
component-name : component port map (signal-mapping); (b) Figure 29: (a) block schematic of counter_main (b) Overview structural architecture Page 25 of 127
Figure 29b gives an overview of the structural architecture. Use this to make the counter work. Signal mapping is done by assigning a signal or value to each in- and output pin of the component. E.g.: clk => MyClockSignal, Enable => 1 By assigning the same signal to different pins, a connection is made between these pins. This is the equivalent of wiring different hardware components together. Try to check the syntax of the design, synthesise and implement this new exercise on the design board. Dont forget to make it your new top-entity. Why does the display only show the number 8?
Page 26 of 127
Try to implement the previous counter, but this time with a scaled-down clock. This should solve the problem encountered in the last exercise. The schematic should look like this:
Clock (50MHz)
Scale factor
Page 27 of 127
VI.
To analyse the VHDL design, a program called ModelSim is used. This program can simulate complete designs or parts of them. Before programming an FPGA, always simulate everything so you know what can be expected during operation. It is possible to damage the hardware when downloading incorrect designs.
Page 28 of 127
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity tstbench is port(outp : OUT std_logic_vector (6 downto 0)); end tstbench; architecture test of tstbench is --- component declarations => adding your design to the test bench -component counter_main is port (clock : IN std_logic; ledout : OUT std_logic_vector (6 downto 0)); end component; --- signal declarations -signal clk : std_logic := '0'; -- generate clocks begin process(clk) begin clk <= not clk after 20 ns; -- 50MHz end process; --- hook up components => connect your design to the correct signals -u1: counter_main port map (clock => clk, ledout => outp); end test; Figure 32: Test Bench example
The after-command can only be used in simulation. It cant be implemented in hardware. By inverting the clock signal every 20ns we make a 50MHz clock. Some programs are able to generate a test bench. But as there is no common graphical user interface for generated test benches, its better to learn to write one by hand. Signals can be initialised to a certain value by using the := operator. This only works in simulation. An FPGA cant automatically preload values to its signals.
Page 29 of 127
3. Compiling files
Compile -> Compile All Errors can be seen by double clicking on the red error line (Compile of ... failed with ... errors). If an error occurs in a certain file (probably the test bench), first try the following: Right click on the file->Properties->VHDL-tab->Use 1993 Language Syntax must be checked
4. Simulate
Simulate->Simulate Select the top-entity file (the test bench). Press OK Right click on the test bench-file and select Add->Add to Wave A new window will open with all the signals from the test bench. Press Run for each time step Analyse the behaviour of the entity by looking at the waveforms.
5. Alternatives
A Logic State Analyser (LSA) can be used to look to the FPGA pins or even at all the signals inside a design. Those systems are really expensive. Some vendors provide an on-chip analyser (Alteras Signal Tap and Xilinx ILA). Unfortunately these are not included in the web-pack version of Quartus.
Page 30 of 127
VII.
Expand the counter with an asynchronous reset and a start/stop button (start counter when pressed, stop counter when pressed again). To get started, an example of a reset is given.
process(clk, reset) process(clk) begin begin if (reset = '0') then if (clk'EVENT and clk='1') then reset code; if (reset = '0') then elsif (clk'EVENT and clk='1') then reset code; synchronous code; end if; end if; synchronous code; end process; end if; end process; (a) (b) Figure 33: Example of an asynchronous (a) and synchronous (b) reset
Page 31 of 127
B) Exotic counter
Expand the basic counter to output following sequence.
Sequence:
01A5FE3C98B2746D
Use a Finite State Machine (FSM) to achieve this (see appendix C). An FSM can easily be implemented in VHDL using the case-statements in combination with an internal state-signal.
Ex.:
type states is (s0, s1, s2, ); signal state : states; begin case state is when s0 => output <= "0010"; state<=s1; when s1 => output <= "0001"; state<=s2; when others => output <= "1001"; state<=s0; end case; Figure 34: Example VHDL FSM
Page 32 of 127
C) Dual-display counter
Expand the basic counter so it can use 2 displays. The range is from 00 to FF. When using the Xilinx Spartan development board, multiplexing is needed. In turn apply the data for the first and second display while changing the select signals (see Figure 35). When the transistor a1 is high, the data will be sent to display one. Other displays can be selected in a similar way.
Page 33 of 127
Enable Clock
4 Counter
Page 34 of 127
Data In 4
Buffer
Parity check
CS 1 0
Muli- TX plexer CS
RX
Buffer 4 CS
Parity check
parity CS
Clock
Clock divider
CLK
Read ready (b) Figure 37: Schematics UART (a) write port (b) read port
Page 35 of 127
Remarks: - All blocks should be synchronous. - A multiplexer can be used to easily send serial data. - Send the serial data at 24.4KHz (=50MHz/2048). If everybody uses the same transmission speed, you can connect to each other later on. - The parity bit is defined as follows: when the amount of 1-bits in the data is odd then the parity bit is set, otherwise it is cleared. - Start bit=0, Stop bit=1, transmit data with LSB first. - Try to sample in the middle of the waveform when the RX signal is stable, not at the edges. Use sampling clock that is 8 or 16 times higher than the UART clock. - The output signals (Busy, Error, Read ready) can be connected to LEDs to view if everything works properly. - For testing, connect pin 2 (TX) and 3 (RX) of the serial connector with a wire. This creates a loop back to easily test your system. - Board schematics can be found in appendix E.
Idle
Idle
Page 36 of 127
B) LCD controller
Another possibility is to make an LCD controller. Try to adapt the previous counters so they are able to output to the LCD display. As the LCD module is only available for the Altera development board, this project cant be made on a Xilinx board. Follow the same procedure as in the previous project.
LCD 10
Figure 39: Block scheme LCD controller Clock mSec 4 Carry Counter Sec 4 Carry Counter Min 4
Counter
Character control: This block generates the commands that need to be sent to the display. On reset, an initialisation is performed. Afterwards it sequentially writes all the characters to be displayed, returns to the starting position and repeats this loop. LCD control: Here the timing for the LCD takes place. For each command, a specific timing is required (See figure 44). This block takes as input the command coming from the previous block and makes sure it is delivered to the display in the correct way.
Page 37 of 127
Pin number 1
2 3 4 5 6 7 8 9 10 11 12 13 14
Symbol
Vss Vcc Vee RS R/W E DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7
Level
0/1 0/1 1, 1->0 0/1 0/1 0/1 0/1 0/1 0/1 0/1
I/O
I I I I/O I/O I/O I/O I/O I/O I/O
Function
Power supply (GND) Power supply (+5V) Contrast adjust 0 = Instruction input 1 = Data input 0 = Write to LCD module 1 = Read from LCD module Enable signal Data bus line 0 (LSB) Data bus line 1 Data bus line 2 Data bus line 3 Data bus line 4 Data bus line 5 Data bus line 6
0/1 I/O Data bus line 7 (MSB) Figure 41: LCD pin configuration
Function set
Write data
Description Execution time Clears display and returns cursor to 1.64mS the home position (address 0). 1.64mS 000000001* Returns cursor to home position (address 0). Also returns display being shifted to the original position. DDRAM contents remains unchanged. 40uS 0 0 0 0 0 0 0 1 I/D S Sets cursor move direction (I/D), specifies to shift the display (S). These operations are performed during data read/write. 40uS 0000001DCB Sets On/Off of all display (D), cursor On/Off and blink of cursor position character (B). 40uS 0 0 0 0 0 1 S/C R/L * * Sets cursor-move or display-shift (S/C), shift direction (R/L). DDRAM contents remains unchanged. 40uS 0 0 0 0 1 DL N F * * Sets interface data length (DL), number of display line (N) and character font (F). 1 0 DATA (see figure 45) Writes data to CGRAM or DDRAM. 40uS Figure 42: LCD commands
Page 38 of 127
Bit name Setting / Status I/D 0 = Decrement cursor position 1 = Increment cursor position
S D C B S/C R/L DL N F 0 = No display shift 0 = Display off 0 = Cursor off 0 = Cursor blink off 0 = Move cursor 0 = Shift left 0 = 4-bit interface 0 = 1/8 or 1/11 Duty (1 line) 0 = 5x7 dots 1 = Display shift 1 = Display on 1 = Cursor on 1 = Cursor blink on 1 = Shift display 1 = Shift right 1 = 8-bit interface 1 = 1/16 Duty (2 lines) 1 = 5x10 dots Figure 43: Bit names
Page 39 of 127
Remarks: - All blocks should be synchronous. - Try to use the build-in PLL/DLL to divide your clock signal. Quartus and ISE have a wizard to make your own PLLs/DLLs. Quartus: Mega wizard Plug-in ISE: Create new source -> IP (CoreGen) - The LCD is very time critical. If you write the data too fast, errors will occur. The display controller needs time to be able to process the commands. - Not all commands take the same time to execute. - Try to make a counter for each character to be displayed. This means that you need 2 timers for the seconds (34sec=>3 & 4). - The other displays (seven segment, LEDs, ..) can be used to output some debug data or help you visualise the process. - Board schematics can be found in appendix E. - Start with something simple and try to expand your project. e.g.: First try to display one character before moving on.
Page 40 of 127
Clock
RX
TX (not used) Clock
UART
Data
Data 8 PWM
Audio
R/W
RX
Address
18
CLK
Memory control: This block takes care of the communications with the SRAM. It consists of a read and a write procedure. Each cycle consists of three synchronous commands as depicted in Figure 47. First initialise SDRAM, afterwards read or write the date and finally restore the bus. Filter(s): The audio coming from the memory is filtered. The coefficients of four FIR-filters, together covering the complete spectrum, are given later in this text (figure 48). PWM: In order to convert the digital data back to an analogue voltage, Pulse Width Modulation is used. Use 8-bit data words.
Read
Page 41 of 127
FIR1
(...-110Hz)
VARIABLE
GAIN
FIR2
(110-630Hz)
VARIABLE
GAIN 6 8
8 FIR3
(630Hz-3.5kHz) VARIABLE
GAIN
FIR4
(3.5kHz-...)
VARIABLE
GAIN
Page 42 of 127
FIR2 (BP 110 - 630 Hz) FIR3 (BP 630 Hz - 3.5 kHz) FIR4 (HP 3.5 kHz) FIR1 (LP 110 Hz) 0.009548 0.001962 -0.000360 0.000905 0.014398 0.006199 -0.010500 0.006026 0.028087 0.018324 -0.016603 -0.009473 0.048371 0.041571 0.000243 -0.023836 0.071792 0.074699 -0.054629 0.057537 0.094288 0.111809 -0.163179 0.048434 0.111923 0.144091 0.004730 -0.298381 0.121593 0.162894 0.386648 0.439930 0.121593 0.162894 0.386648 -0.298381 0.111923 0.144091 0.004730 0.048434 0.094288 0.111809 -0.163179 0.057537 0.071792 0.074699 -0.054629 -0.023836 0.048371 0.041571 0.000243 -0.009473 0.028087 0.018324 -0.016603 0.006026 0.014398 0.006199 -0.010500 0.000905 0.009548 0.001962 -0.000360 0 Figure 50: Possible filter coefficients (FIR Hamming window)
Figure 51: Visual Basic interface The Visual Basic program reads an audio file with consists of 8-bit words, sampled at 12.5kHz. It will send this data to its serial port.
Remarks: - All blocks should be synchronous. - To be able to use the audio lineout, an extension board (Lancelot VGA) is available. Attach this board correctly to the development kit before powering up. Therefore use connectors J11, J12 and J13. - Make an interface so you can view and change some settings (e.g. gain). - The values given in figure 50 are generated by MatLab. They need to be adapted before they can be used in VHDL. - Two SRAMs are used in parallel to have a 24-bit wide memory. Some signals are shared, other signals are IC specific. See pin configuration in appendix A for more details. - Board schematics can be found in appendix E.
Page 43 of 127
IX.
(a)
Page 44 of 127
Switches SW0 SW1 SW2 SW3 LEDs D0 D1 D2 D3 D4 D5 D6 D7 UART TDX RDX SRAM CS WE OE BHE0 BHE1 BLE0 BLE1 A0 A1 A2 A3 A4 A5 A6 A9 A12 A15
W5 W6 AB2 AB1
7-segment 1 A B C D E F G DP 7-segment 2 A B C D E F G DP
U21 Y28
K3 M7 M8 H3 L7 L8 H2 H1 L6 L5 J4 K17
A7 E6 A8 A10 D6 A11 A13 C6 A14 A16 D8 A17 Figure 53: Pin configuration Stratix
A6 A7 C7 C8
Page 45 of 127
(a)
(b)
(c)
IMPORTANT:
Connect the I/O board to connectors J6(E) and J7(F) otherwise the pins bellow arent correct.
P44 P46 P48 UART P55 TX P57 RX P59 P61 P80 Clock P63 Figure 55: Pin configuration Spartan
P17 P20 P22 P24 P29 P31 P34 P36 P45 P47 P49 P56
P201 P202
Page 46 of 127
(b)
Buttons BTN0 BTN1 BTN2 BTN3 LEDs LD0 LD1 LD2 LD3 LD4 LD5 LD6 LD7
K12 P14 L12 N14 UART P13 TX N12 RX P12 P11 T9 Clock Figure 55: Pin configuration Spartan
E14 G13 N15 P15 R16 F13 N16 P16 D14 G14 F14 E13
R13 T13
Page 47 of 127
X. Appendix B (Operators)
The logical operators NOT, AND, OR, NAND, NOR, and XOR can be used with any bit type or bit vector. When used as operators on bits they have their usual meaning. When used with bit vectors, the bit vectors must have the same number of elements, and the operation is performed bit wise. For example, "00101001" xor "11100101" results in "11001100".
Note: just as '0' and '1' represent constant bit values, constant bit vectors can be written in VHDL as a list of bit values in double quotes. For example, if d is a bit vector(3 downto 0) the following statement gives d the permanent values d(3)='1', d(2)='1', d(1)='0', and d(0)='0'.
d<="1100"; Also predefined are the normal relational operators. They are =, /=, <, <=, > and >= and have their usual meanings (/= denotes the not equal operator). The result of all these operators is a boolean value (TRUE or FALSE). The arguments to the = and /= operators may be of any type. The arguments of the <, <=, > and >= operators may be any scalar type (integer, real, and physical types) or the bit vector type. If the arguments are bit vectors, then the arguments must be the same length and the result is TRUE only if the relation is true for each corresponding element of the array arguments. The &-operator is a built-in VHDL operator that performs the concatenation of bit vectors. For example, with the following declarations: signal a: bit vector (3 downto 0); signal b: bit vector (7 downto 0); The following statement would connect a to the right half of b and make the left half of b constant '0'. b<="0000" & a;
Page 48 of 127
XI.
A finite state machine (FSM) is an abstract computational device that has a finite number of different states. The system always resides in a specific state. According to the input, the transition to the next one can be selected. With each state a certain output is generated. Thus, by describing each state individually and the transitions between them, a complete design can be modelled. FSM can represent almost every possible system, also the complex ones. Therefore these FSMs are used frequently. Following figure will explain a FSM model.
S1 S6 S2
S5
S3
S4
For each state an output vector is defined. E.g.: State 1: output <= 0100; State 2: output <= 1111; For each state a transition is defined to another state, depending on the input. E.g.: State 1: to S1 if input=1 to S2 if input=0 State 2: to S1 if input=1 to S3 if input=0
Page 49 of 127
XII.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity button_to_led is port( sw : IN std_logic_vector (3 downto 0); ledout : OUT std_logic_vector (3 downto 0) ); end button_to_led; architecture button_to_led_arch of button_to_led is begin ledout <= sw; end button_to_led_arch;
Page 50 of 127
Page 51 of 127
Page 52 of 127
D) 4-bit counter
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity counter_main is port( clock : IN std_logic; ledout : OUT std_logic_vector (6 downto 0) ); end counter_main; architecture counter_main_arch of counter_main is component counter port( clk : IN std_logic; c : OUT std_logic_vector (3 downto 0) ); end component; component decode7segment port( code : IN std_logic_vector (3 downto 0); seg7 : OUT std_logic_vector (6 downto 0) ); end component; signal s_waarde : std_logic_vector (3 downto 0); begin LED1 : decode7segment port map( code => s_waarde, seg7 => ledout ); count1 : counter port map( clk => clock, c => s_waarde ); end counter_main_arch;
Page 53 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity counter is port( clk : IN std_logic; c : OUT std_logic_vector (3 downto 0) ); end counter; architecture counter_arch of counter is signal tel : std_logic_vector (3 downto 0) :="0000"; --initialisation for simulator begin process(clk) begin if (clk'EVENT and clk='1') then tel <= tel + 1; end if; end process; c <= tel; end counter_arch;
Page 54 of 127
Page 55 of 127
count1 : counter port map( clk => s_pll_clock, c => s_waarde ); pll1 : downscale port map( clkin => clock, decimator => "1111", clkout => s_pll_clock ); end counter_pll_main_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity downscale is port( clkin : IN std_logic; decimator : IN std_logic_vector (3 downto 0); clkout : OUT std_logic ); end downscale; architecture down_arch of downscale is signal teller : std_logic_vector(21 downto 0); signal s_out : std_logic; begin process(clkin) begin if (clkin'EVENT and clkin='1') then teller <= teller - 1; if teller = 0 then teller <= decimator & "000000000000000000"; s_out <= not s_out; end if; end if; end process; clkout <= s_out; end down_arch;
Page 56 of 127
F) Advanced counter
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity counter_rst_main is port( clock : IN std_logic; r : IN std_logic; ss : IN std_logic; ledout : OUT std_logic_vector (6 downto 0) ); end counter_rst_main; architecture counter_rst_main_arch of counter_rst_main is component counter_adv port( clk : IN std_logic; reset : IN std_logic; start_stop : IN std_logic; c : OUT std_logic_vector (3 downto 0) ); end component; component decode7segment port( code : IN std_logic_vector (3 downto 0); seg7 : OUT std_logic_vector (6 downto 0) ); end component; component downscale port( clkin : IN std_logic; decimator : IN std_logic_vector (3 downto 0); clkout : OUT std_logic ); end component; signal s_waarde : std_logic_vector (3 downto 0); signal s_pll_clock : std_logic;
Page 57 of 127
begin LED1 : decode7segment port map( code => s_waarde, seg7 => ledout ); count1 : counter_adv port map( clk => s_pll_clock, reset => r, start_stop => ss, c => s_waarde ); pll1 : downscale port map( clkin => clock, decimator => "1111", clkout => s_pll_clock ); end counter_rst_main_arch;
Page 58 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity counter_adv is port( clk : IN std_logic; reset : IN std_logic; start_stop : IN std_logic; c : OUT std_logic_vector (3 downto 0) ); end counter_adv; architecture counter_arch of counter_adv is signal tel : std_logic_vector(3 downto 0); signal run : std_logic := '0'; signal vorige_ss : std_logic; begin process(clk, reset) begin if (reset = '0') then tel <= 0000; elsif (clk'EVENT and clk='1') then if run = '1' then tel <= tel + 1; if tel > 8 then tel <= 0000; end if; end if; if (start_stop = '0' and vorige_ss = 1) then run <= not run; end if; vorige_ss<=start_stop; end if; c <= tel; end process; end counter_arch;
Page 59 of 127
G)Exotic counter
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity exotic_main is port( clock : IN std_logic; ledout : OUT std_logic_vector (6 downto 0) ); end exotic_main; architecture exotic_arch of exotic_main is component exotic_counter port( clk : IN std_logic; c : OUT std_logic_vector (3 downto 0) ); end component; component decode7segment port( code : IN std_logic_vector (3 downto 0); seg7 : OUT std_logic_vector (6 downto 0) ); end component; component downscale port( clkin : IN std_logic; decimator : IN std_logic_vector (3 downto 0); clkout : OUT std_logic ); end component; signal s_waarde2 : std_logic_vector (3 downto 0); signal s_pll_clock : std_logic; begin LED2 : decode7segment port map( code => s_waarde2, seg7 => ledout );
Page 60 of 127
count1 : exotic_counter port map( clk => s_pll_clock, c => s_waarde2 ); pll1 : downscale port map( clkin => clock, decimator => "1111", clkout => s_pll_clock ); end exotic_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity exotic_counter is port ( clk : IN std_logic; c : OUT std_logic_vector (3 downto 0) ); end exotic_counter; architecture exotic_counter_arch of exotic_counter is type state is (p0,p1,p2,p3,p4,p5,p6,p7,p8,p9); signal toestand : state; begin process(clk) begin if (clk'EVENT and clk='1') then case toestand is when p0 => c <= "0000"; toestand<=p1; when p1 => c <= "0001"; toestand<=p2; when p2 => c <= "0101"; toestand<=p3; when p3 => c <= "0011"; toestand<=p4; when p4 => c <= "1001"; toestand<=p5;
Page 61 of 127
when p5 => c <= "1000"; toestand<=p6; when p6 => c <= "0010"; toestand<=p7; when p7 => c <= "0111"; toestand<=p8; when p8 => c <= "0100"; toestand<=p9; when others => c <= "0110"; toestand<=p0; end case; end if; end process; end exotic_counter_arch;
Page 62 of 127
Page 63 of 127
Begin LED1 : decode7segment port map( code => s_waarde1, seg7 => ledout1 ); LED2 : decode7segment port map( code => s_waarde2, seg7 => ledout2 ); count1 : counter_dual port map( clk => s_pll_clock, reset => r, start_stop => ss, c1 => s_waarde1, c2 => s_waarde2 ); pll1 : downscale port map( clkin => clock, decimator => "1111", clkout => s_pll_clock ); end counter_dual_main_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity counter_dual is port ( clk : IN std_logic; reset : IN std_logic; start_stop : IN std_logic; c1 : OUT std_logic_vector (3 downto 0); c2 : OUT std_logic_vector (3 downto 0) ); end counter_dual; architecture counter_dual of counter_dual is signal tel1 : std_logic_vector(3 downto 0); signal tel2 : std_logic_vector(3 downto 0); signal run : std_logic := '0'; signal vorig_ss : std_logic;
Page 64 of 127
begin process(clk, reset) begin if (reset = '0') then tel1 <= 0000; tel2 <= 0000; elsif (clk'EVENT and clk='1') then if run = '1' then tel1 <= tel1 + 1; if tel1 > 8 then tel1 <= 0000; tel2 <= tel2 + 1; if tel2 > 8 then tel2 <= 0000; end if; end if; end if; if (start_stop=1 and vorig_ss = '0') then run <= not run; end if; vorig_ss<=start_stop; end if; c1 <=tel1; c2 <= tel2; end process; end counter_dual;
Page 65 of 127
Page 66 of 127
Begin LED1 : decode7segment port map( code => s_waarde_out, seg7 => ledout1 ); count1 : counter_dual port map( clk => s_pll_clock, reset => not r, start_stop => not ss, c1 => s_waarde1, c2 => s_waarde2 ); pll1 : downscale port map( clkin => clock, decimator => "1111", clkout => s_pll_clock ); process(clock) begin if (clock'EVENT and clock='1') then if (delay=0) then if (s_select='1') then s_waarde_out<=s_waarde1; select1<='0'; select2<='1'; else s_waarde_out<=s_waarde2; select1<='1'; select2<='0'; end if; s_select<= not s_select; end if; delay<=delay+1; end if; end process; end counter_dual_main_arch;
Page 67 of 127
J) UART project
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity datatransfer is port( send : IN std_logic; sw : IN std_logic; ledout1 : OUT std_logic_vector (6 downto 0); ledout2 : OUT std_logic_vector (6 downto 0); clock : IN std_logic; uart_rx : IN std_logic; uart_tx : OUT std_logic; ); end datatransfer; architecture datatransfer_arch of datatransfer is component counter port( clk : IN std_logic; addone : IN std_logic; c : OUT std_logic_vector (3 downto 0) ); end component; component decode7segment port( code : IN std_logic_vector (3 downto 0); seg7 : OUT std_logic_vector (6 downto 0) ); end component; component UART port( dataIn : IN std_logic_vector (7 downto 0); loadData : IN std_logic; dataOut : OUT std_logic_vector (7 downto 0); readDataReady : OUT std_logic; busy : OUT std_logic; error : OUT std_logic; clk : IN std_logic; rst : IN std_logic; rx : IN std_logic; tx : OUT std_logic ); end component;
Page 68 of 127
signal dIn : std_logic_vector (7 downto 0); signal dOut : std_logic_vector (7 downto 0); signal rdr : std_logic; signal b : std_logic; signal e : std_logic; begin LED1 : decode7segment port map( code => dIn(3 downto 0), seg7 => ledout2 ); LED2 : decode7segment port map( code => dOut(3 downto 0), seg7 => ledout1 ); count1 : counter port map( clk => clock, addone => not sw, c => dIn(3 downto 0) ); uart1 : UART port map( dataIn => dIn, loadData => not send, dataOut => dOut, readDataReady => rdr, busy => b, error => e, clk =>clock, rst => '0', rx => uart_rx, tx => uart_tx ); end datatransfer_arch;
Page 69 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity UART is port( dataIn : IN std_logic_vector (7 downto 0); loadData : IN std_logic; dataOut : OUT std_logic_vector (7 downto 0); readDataReady : OUT std_logic; busy : OUT std_logic; error : OUT std_logic; clk : IN std_logic; rst : IN std_logic; rx : IN std_logic; tx : OUT std_logic ); end UART; architecture UART_arch of UART is component mux port( muxIn : IN std_logic_vector (15 downto 0); sel : IN std_logic_vector (3 downto 0); clkIn : IN std_logic; muxOut : OUT std_logic ); end component; component parity port( parIn : IN std_logic_vector (7 downto 0); clkIn : IN std_logic; calc : IN std_logic; parOut : OUT std_logic ); end component; component buf port( bufIn : IN std_logic_vector (7 downto 0); clk : IN std_logic; send : IN std_logic; bufOut : OUT std_logic_vector (7 downto 0) ); end component;
Page 70 of 127
component UART_writecontrol port( loadData : IN std_logic; wr_busy : OUT std_logic; clkIn : IN std_logic; rstIn : IN std_logic; shift : OUT std_logic; par : OUT std_logic; mux_sel : OUT std_logic_vector (3 downto 0) ); end component; component UART_readcontrol port( rxIn : IN std_logic; par : IN std_logic; ready : OUT std_logic; err : OUT std_logic; clkIn : IN std_logic; readOut : OUT std_logic_vector (7 downto 0) ); end component; signal data_in_buf : std_logic_vector (7 downto 0); signal parbit : std_logic; signal calc_parity : std_logic; signal shiftData : std_logic; signal muxData : std_logic_vector (15 downto 0); signal s_sel : std_logic_vector (3 downto 0); signal readPar : std_logic; signal readReg : std_logic_vector (7 downto 0); signal readReady : std_logic; begin mux1 : mux port map( muxIn => muxData, sel => s_sel, clkIn => clk, muxOut => tx );
Page 71 of 127
parity1 : parity port map( parIn => data_in_buf, clkIn => clk, calc => calc_parity, parOut => parbit ); buf1 : buf port map( bufIn => dataIn, clk => clk, send => shiftData, bufOut => data_in_buf ); write1 : UART_writecontrol port map( loadData => loadData, wr_busy => busy, clkIn => clk, rstIn => rst, shift => shiftData, par => calc_parity, mux_sel => s_sel ); read1 : UART_readcontrol port map( rxIn => rx, par => readPar, ready => readReady, err => error, clkIn => clk, readOut => readReg ); buf2 : buf port map( bufIn => readReg, clk => clk, send => readReady, bufOut => dataOut );
Page 72 of 127
parity2 : parity port map( parIn => readReg, clkIn => clk, calc => clk, parOut => readPar ); muxData <= "10" & data_in_buf & parbit & "00000"; readDataReady <= readReady; end UART_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity parity is port( parIn : IN std_logic_vector (7 downto 0); ckIn : IN std_logic; calc : IN std_logic; parOut : OUT std_logic ); end parity; architecture parity_arch of parity is signal vorige_calc : std_logic; signal count : std_logic_vector(3 downto 0); begin process(clkIn) begin if (clkIn'EVENT and clkIn='1') then vorige_calc<=calc; if calc='1' and vorige_calc='0' then count <= (("000" & parIn(0)) + ("000" & parIn(1)) + ("000" & parIn(2)) + ("000" & parIn(3)) + ("000" & parIn(4)) + ("000" & parIn(5)) + ("000" & parIn(6)) + ("000" & parIn(7))); vorige_calc<='1'; end if; parOut <= count(0); end if; end process; end parity_arch;
Page 73 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity mux is port( muxIn : IN std_logic_vector (15 downto 0); sel : IN std_logic_vector (3 downto 0); clkIn : IN std_logic; muxOut : OUT std_logic ); end mux; architecture mux_arch of mux is begin process(clkIn) begin if (clkIn'EVENT and clkIn='1') then case sel is when "0000" => muxOut <= muxIn(0); when "0001" => muxOut <= muxIn(1); when "0010" => muxOut <= muxIn(2); when "0011" => muxOut <= muxIn(3); when "0100" => muxOut <= muxIn(4); when "0101" => muxOut <= muxIn(5); when "0110" => muxOut <= muxIn(6); when "0111" => muxOut <= muxIn(7); when "1000" => muxOut <= muxIn(8); when "1001" => muxOut <= muxIn(9); when "1010" => muxOut <= muxIn(10); when "1011" => muxOut <= muxIn(11); when "1100" => muxOut <= muxIn(12); when "1101" => muxOut <= muxIn(13); when "1110" => muxOut <= muxIn(14);
Page 74 of 127
when "1111" => muxOut <= muxIn(15); end case; end if; end process; end mux_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity buf is port( bufIn : IN std_logic_vector (7 downto 0); clk : IN std_logic; send : IN std_logic; bufOut : OUT std_logic_vector (7 downto 0) ); end buf; architecture buf_arch of buf is signal vorige : std_logic :='0'; begin process(clk) begin if (clk'EVENT and clk='1') then if (vorige='0' and send='1') then bufOut <= bufIn; end if; vorige <= send; end if; end process; end buf_arch;
Page 75 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity UART_writecontrol is port( loadData : IN std_logic; wr_busy : OUT std_logic; clkIn : IN std_logic; rstIn : IN std_logic; shift : OUT std_logic; par : OUT std_logic; mux_sel : OUT std_logic_vector (3 downto 0) ); end UART_writecontrol; architecture UART_wc_arch of UART_writecontrol is type state is (idle,load,start,d0,d1,d2,d3,d4,d5,d6,d7,pari,stop); signal toestand : state; signal vorige_loadData : std_logic := '0'; signal delay : std_logic_vector (9 downto 0) := "0000000000"; begin process(clkIn, rstIn) begin if rstIn='1' then toestand <= idle; elsif (clkIn'EVENT and clkIn='1') then if delay=0 then delay <= "1000000000"; case toestand is when idle => if loadData='1' and vorige_loadData='0' then toestand <= load; wr_busy <= '1'; else wr_busy <= '0'; shift <= '0'; par <= '0'; mux_sel <= "1111"; end if; vorige_loadData <= loadData;
Page 76 of 127
when load => shift <= '1'; toestand <= start; when start => shift <= '0'; par <= '1'; mux_sel <= "1110"; toestand <= d0; when d0 => par <= '0'; mux_sel <= "0110"; toestand <= d1; when d1 => mux_sel <= "0111"; toestand <= d2; when d2 => mux_sel <= "1000"; toestand <= d3; when d3 => mux_sel <= "1001"; toestand <= d4; when d4 => mux_sel <= "1010"; toestand <= d5; when d5 => mux_sel <= "1011"; toestand <= d6; when d6 => mux_sel <= "1100"; toestand <= d7; when d7 => mux_sel <= "1101"; toestand <= pari; when pari => mux_sel <= "0101"; toestand <= stop; when stop => mux_sel <= "1111"; wr_busy <= '0'; toestand <= idle; when others => toestand <= idle; end case; else delay <= delay - 1; end if; end if; end process; end UART_wc_arch;
Page 77 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity UART_readcontrol is port( rxIn : IN std_logic; par : IN std_logic; ready : OUT std_logic; err : OUT std_logic; clkIn : IN std_logic; readOut : OUT std_logic_vector (7 downto 0) ); end UART_readcontrol; architecture UART_rc_arch of UART_readcontrol is type state is (idle,d0,d1,d2,d3,d4,d5,d6,d7,pari,chk_par, w1); signal toestand : state; signal parity : std_logic; signal clk_div : std_logic_vector (9 downto 0) := "0000000000"; begin process(clkIn) begin if (clkIn'EVENT and clkIn='1') then if clk_div = 0 then case toestand is when idle => if rxIn='0' then err <= '0'; ready <= '0'; clk_div <= "1100000000"; toestand <= d0; else clk_div <= "0000100000"; end if; when d0 => readOut(0) <= rxIn; clk_div <= "1000000000"; toestand <= d1; when d1 => readOut(1) <= rxIn; clk_div <= "1000000000"; toestand <= d2;
Page 78 of 127
when d2 => readOut(2) <= rxIn; clk_div <= "1000000000"; toestand <= d3; when d3 => readOut(3) <= rxIn; clk_div <= "1000000000"; toestand <= d4; when d4 => readOut(4) <= rxIn; clk_div <= "1000000000"; toestand <= d5; when d5 => readOut(5) <= rxIn; clk_div <= "1000000000"; toestand <= d6; when d6 => readOut(6) <= rxIn; clk_div <= "1000000000"; toestand <= d7; when d7 => readOut(7) <= rxIn; clk_div <= "1000000000"; toestand <= pari; when pari => parity <= rxIn; clk_div <= "1000000000"; toestand <= chk_par; when chk_par => if par=parity then ready <= '1'; else err <= '1'; end if; clk_div <= "1000000000"; toestand <= w1; when w1 => clk_div <= "1000000000"; toestand <= idle; when others => toestand <= idle; end case; else clk_div <= clk_div - 1; end if; end if; end process; end UART_rc_arch;
Page 79 of 127
K) LCD project
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity lcd_proj is port( clk : IN std_logic; sw : IN std_logic_vector(1 downto 0); lcd_out : OUT std_logic_vector(10 downto 0) ); end lcd_proj; architecture lcd_watch_arch of lcd_proj is signal dat : std_logic_vector (9 downto 0); signal en : std_logic; signal srst : std_logic; signal scaled_clk : std_logic; component counter is port ( clock : IN std_logic; reset : IN std_logic; start_stop : IN std_logic; start : OUT std_logic; data : OUT std_logic_vector(9 downto 0) ); end component; component lcd_control is port ( clock_in : IN std_logic; data : IN std_logic_vector(9 downto 0); start : IN std_logic; lcd : OUT std_logic_vector(10 downto 0) ); end component; component pll IS --GENERATED BY Mega wizard Plug-in port ( inclk0 : IN STD_LOGIC := 0; c0 : OUT STD_LOGIC ); end component;
Page 80 of 127
begin c1 : counter port map( clock => scaled_clk, reset => srst, start_stop => sw(0), start => en, data => dat ); driver1 : lcd_control port map( clock_in => scaled_clk, data => dat, start => en, lcd => lcd_out ); pll1 : pll port map( inclk0 => clk, c0 => scaled_clk ); srst <= not sw(1); end lcd_watch_arch;
Page 81 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity counter is port ( clock : IN std_logic; reset : IN std_logic; start_stop : IN std_logic; data : OUT std_logic_vector(9 downto 0); start : OUT std_logic ); end counter; architecture counter_arch of counter is signal enable100hz : std_logic; signal enable10hz : std_logic; signal enablesec : std_logic; signal enable10sec : std_logic; signal enablemin : std_logic; signal enable10min : std_logic; signal run : std_logic := 0; signal data_honderd0 : std_logic_vector (15 downto 0); signal data_honderd1 : std_logic_vector (15 downto 0); signal data_sec0 : std_logic_vector (15 downto 0); signal data_sec1 : std_logic_vector (15 downto 0); signal data_min0 : std_logic_vector (15 downto 0); signal data_min1 : std_logic_vector (15 downto 0); signal h_out : std_logic_vector (7 downto 0); signal s_out : std_logic_vector (7 downto 0); signal m_out : std_logic_vector (7 downto 0); component count24bit is port ( clock_in : IN std_logic; enable : IN std_logic; rst : IN std_logic; max : IN std_logic_vector(15 downto 0); carry : OUT std_logic; data : OUT std_logic_vector(15 downto 0) ); end component;
Page 82 of 127
component display_control is port ( clock_in : IN std_logic; honderd : IN std_logic_vector(7 downto 0); sec : IN std_logic_vector(7 downto 0); min : IN std_logic_vector(7 downto 0); rst : IN std_logic; data_out : OUT std_logic_vector(9 downto 0); go : OUT std_logic ); end component; begin downscale_5Mto100 : count24bit port map( clock_in => clock, enable => run, rst => reset, max => 0000111110011111, carry => enable100hz ); count_honderd0 : count24bit port map( clock_in => clock, enable => enable100hz, rst => reset, max => 0000000000001001, carry => enable10hz, data => data_honderd0 ); count_honderd1 : count24bit port map( clock_in => clock, enable => enable10hz, rst => reset, max => 0000000000001001, carry => enablesec, data => data_honderd1 ); count_sec0 : count24bit port map( clock_in => clock, enable => enablesec, rst => reset, max => 0000000000001001, carry => enable10sec, data => data_sec0 );
Page 83 of 127
count_sec1 : count24bit port map( clock_in => clock, enable => enable10sec, rst => reset, max => 0000000000000101, carry => enablemin, data => data_sec1 ); count_min0 : count24bit port map( clock_in => clock, enable => enablemin, rst => reset, max => 0000000000001001, carry => enable10min, data => data_min0 ); count_min1 : count24bit port map( clock_in => clock, enable => enable10min, rst => reset, max => 0000000000000101, data => data_min1 ); d_con1 : display_control port map( clock_in => clock, honderd => h_out, sec => s_out, min => m_out, data_out => data, go => start, rst => reset ); process(start_stop) begin if (start_stop = 0) then run <= not run; end if; end process; h_out <= data_honderd1(3 downto 0) & data_honderd0(3 downto 0); s_out <= data_sec1(3 downto 0) & data_sec0(3 downto 0); m_out <= data_min1(3 downto 0) & data_min0(3 downto 0); end counter_arch;
Page 84 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity count24bit is port( clock_in : IN std_logic; enable : IN std_logic; rst : IN std_logic; max : IN std_logic_vector(15 downto 0); carry : OUT std_logic; data : OUT std_logic_vector (15 downto 0) ); end count24bit; architecture count24bit_arch of count24bit is signal count : std_logic_vector(15 downto 0) := 0000000000000001; signal s_carry : std_logic :=0; begin process(clock_in, rst) begin if (rst = 1) then count <= max; elsif (clock_inEVENT and clock_in = 1) then if enable = 1 then count <= count 1; if count = 0 then count <= max; s_carry <= 1; end if; end if; if s_carry = 1 then s_carry <= 0; end if; end if; data <= max-count; carry <= s_carry; end process; end count24bit_arch;
Page 85 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity display_control is port ( clock_in : IN std_logic; honderd : IN std_logic_vector(7 downto 0); sec : IN std_logic_vector(7 downto 0); min : IN std_logic_vector(7 downto 0); rst : IN std_logic; go : OUT std_logic; data_out : OUT std_logic_vector(9 downto 0) ); end display_control; architecture display_control_arch of display_control is signal space : std_logic_vector(7 downto 0); signal delay : std_logic_vector(3 downto 0); type states is (s0,sw1,s1,sw2,s2,sw3,s3,sw4,p0,w1,p1,w2,p2,w3,p3,w4,p4,w5,p5, w6,p6,w7,p7,w8,p8,w9,stop); signal state : states; begin process(clock_in,rst) variable I : std_logic_vector(26 downto 0); begin if (rst=1) then state<=s0; delay<=1111; elsif (clock_inEVENT and clock_in=1) then --send data case state is when s0 => if delay>0 then delay<=delay-1; else data_out <= 0000011100; state <= sw1; delay<=1111; go<=1; end if; when sw1 => go<=0; if delay>0 then delay<=delay-1; else state <= s1; end if;
Page 86 of 127
when s1 => data_out <= 0000110000; state <= sw2; delay<=1111; go<=1; when sw2 => go<=0; if delay>0 then delay<=delay-1; else state <= s2; end if; when s2 => data_out <= 0001100000; state <= sw3; delay<=1111; go<=1; when sw3 => go<=0; if delay>0 then delay<=delay-1; else state <= s3; end if; when s3 => data_out <= 0010000000; state <= sw4; delay<=1111; space<=11111111; go<=1; when sw4 => go<=0; if delay>0 then delay<=delay-1; else if space>0 then space<=space-1; delay<=1111; else state <= p0; end if; end if; when p0 => data_out <= (10 & min(4) & min(5) & min(6) & min(7) & 1100); state <= w1; delay<=1111; go<=1;
Page 87 of 127
when w1 => go<=0; if delay>0 then delay<=delay-1; else state <= p1; end if; when p1 => data_out <= (10 & min(0) & min(1) & min(2) & min(3) & 1100); state <= w2; delay<=1111; go<=1; when w2 => go<=0; if delay>0 then delay<=delay-1; else state <= p2; end if; when p2 => data_out <= 1001011100; state <= w3; delay<=1111; go<=1; when w3 => go<=0; if delay>0 then delay<=delay-1; else state <= p3; end if; when p3 => data_out <= (10 & sec(4) & sec(5) & sec(6) & sec(7) & 1100); state <= w4; delay<=1111; go<=1; when w4 => go<=0; if delay>0 then delay<=delay-1; else state <= p4; end if;
Page 88 of 127
when p4 => data_out <= (10 & sec(0) & sec(1) & sec(2) & sec(3) & 1100); state <= w5; delay<=1111; go<=1; when w5 => go<=0; if delay>0 then delay<=delay-1; else state <= p5; end if; when p5 => data_out <= 1001011100; state <= w6; delay<=1111; go<=1; when w6 => go<=0; if delay>0 then delay<=delay-1; else state <= p6; end if; when p6 => data_out <= (10 & honderd(4) & honderd(5) & honderd(6) & honderd(7) & 1100); state <= w7; delay<=1111; go<=1; when w7 => go<=0; if delay>0 then delay<=delay-1; else state <= p7; end if; when p7 => data_out <= (10 & honderd(0) & honderd(1) & honderd(2) & honderd(3) & 1100); state <= w8; delay<=1111; go<=1;
Page 89 of 127
when w8 => go<=0; if delay>0 then delay<=delay-1; else state <= p8; end if; when p8 => go <=1; data_out <= 0001000000; delay<=1111; space<=11111111; state<=w9; when w9 => go<=0; if delay>0 then delay<=delay-1; else if space>0 then space<=space-1; delay<=1111; else state<=p0; end if; end if; when stop => when others => state <= s0; end case; end if; end process; end display_control_arch;
Page 90 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity lcd_control is port( clock_in : IN std_logic; data : IN std_logic_vector(9 downto 0); start : in std_logic; lcd : OUT std_logic_vector(10 downto 0) ); end lcd_control; architecture lcd_control_arch of lcd_control is signal cmd : std_logic_vector(9 downto 0); signal en : std_logic; type states is (s0,s1,s2,s3); signal state : states; begin process(clock_in, start) begin if (start=1) then state<=s0; elsif (clock_inEVENT and clock_in=1) then case state is when s0 => cmd<=data; en<=0; state <= s1; when s1 => en<=1; state <= s2; when s2 => en<=0; state<=s3; when s3 => end case; end if; lcd <= en & cmd; end process; end lcd_control_arch;
Page 91 of 127
Page 92 of 127
component PWM is port( clock_in : IN std_logic; --50MHz data_in : IN std_logic_vector(7 downto 0); pwm_out : OUT std_logic ); end component; component EQ_effect is port( clock_in : IN std_logic; --50MHz data_in : IN std_logic_vector(7 downto 0); data_out : OUT std_logic_vector(7 downto 0); enable : IN std_logic; amp0 : IN std_logic_vector(2 downto 0); amp1 : IN std_logic_vector(2 downto 0); amp2 : IN std_logic_vector(2 downto 0); amp3 : IN std_logic_vector(2 downto 0) ); end component; component decode7segment is port( code : IN std_logic_vector (3 downto 0); seg7 : OUT std_logic_vector (6 downto 0) ); end component; signal sample : std_logic_vector(7 downto 0); signal delay_audio : std_logic_vector(7 downto 0); signal sample_rate : std_logic; signal bhe : std_logic; signal ble : std_logic; signal audio_out : std_logic; signal amp0 : std_logic_vector(2 downto 0); signal amp1 : std_logic_vector(2 downto 0); signal amp2 : std_logic_vector(2 downto 0); signal amp3 : std_logic_vector(2 downto 0); signal vorig_l : std_logic; signal vorig_r : std_logic; signal vorig_u : std_logic; signal vorig_d : std_logic; signal buf_l : std_logic; signal buf_r : std_logic;
Page 93 of 127
signal buf_u : std_logic; signal buf_d : std_logic; signal sel : std_logic_vector(1 downto 0); signal seg_in : std_logic_vector(3 downto 0); signal buf_rst : std_logic; signal rx : std_logic; begin input : input_control port map( clock_in => clock, rx_in => rx, data_out => sample, enable_out => sample_rate, rst => buf_rst, sram_oe => oe, sram_bhe => bhe, sram_ble => ble, sram_cs => cs, sram_we => we, sram_adr => adr_out, sram_data => data_inout ); pwm1 : PWM port map( clock_in => clock, data_in => delay_audio, pwm_out => audio_out ); eff1 : EQ_effect port map( clock_in => clock, data_in => sample, data_out => delay_audio, enable => sample_rate, amp0 => amp0, amp1 => amp1, amp2 => amp2, amp3 => amp3 );
Page 94 of 127
segm7 : decode7segment port map( code => seg_in, seg7 => seg7 ); bhe0<=bhe; bhe1<=bhe; ble0<=ble; ble1<=ble; left<= audio_out; right<= audio_out; uart_tx<='1'; buf_rst<=not reset; process(clock) begin if (clock'EVENT and clock='1') then if (buf_l='1' and vorig_l='0') then if sel>"00" then sel<=sel-1; end if; end if; if (buf_r='1' and vorig_r='0') then if sel<"11" then sel<=sel+1; end if; end if; if (buf_u='1' and vorig_u='0') then case sel is when "00" => if amp0<"111" then amp0<=amp0+1; end if; when "01" => if amp1<"111" then amp1<=amp1+1; end if; when "10" => if amp2<"111" then amp2<=amp2+1; end if; when "11" => if amp3<"111" then amp3<=amp3+1; end if; end case; end if;
Page 95 of 127
if (buf_d='1' and vorig_d='0') then case sel is when "00" => if amp0>"00" then amp0<=amp0-1; end if; when "01" => if amp1>"000" then amp1<=amp1-1; end if; when "10" => if amp2>"000" then amp2<=amp2-1; end if; when "11" => if amp3>"000" then amp3<=amp3-1; end if; end case; end if; vorig_l<=buf_l; vorig_r<=buf_r; vorig_u<=buf_u; vorig_d<=buf_d; buf_l<=not buts(0); buf_r<=not buts(1); buf_u<=not buts(2); buf_d<=not buts(3); rx<=uart_rx; case sel is when "00" => leds<=11000000; seg_in<='0' & amp0; when "01" => leds<=00110000; seg_in<='0' & amp1; when "10" => leds<=00001100; seg_in<='0' & amp2; when "11" => leds<=00000011; seg_in<='0' & amp3; end case; end if; end process; end audio_arch;
Page 96 of 127
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity input_control is port( clock_in : IN std_logic; --50MHz rx_in : IN std_logic; data_out : OUT std_logic_vector(7 downto 0); enable_out : OUT std_logic; rst : IN std_logic; sram_oe : OUT std_logic; sram_bhe : OUT std_logic; sram_ble : OUT std_logic; sram_cs : OUT std_logic; sram_we : OUT std_logic; sram_adr : OUT std_logic_vector(17 downto 0); sram_data : INOUT std_logic_vector(23 downto 0) ); end input_control; architecture in_arch of input_control is component UART is port( dataIn : IN std_logic_vector (7 downto 0); loadData : IN std_logic; dataOut : OUT std_logic_vector (7 downto 0); readDataReady : OUT std_logic; busy : OUT std_logic; error : OUT std_logic; mode : IN std_logic_vector(1 downto 0); clk : IN std_logic; rst : IN std_logic; rx : IN std_logic; tx : OUT std_logic ); end component;
Page 97 of 127
component mem_control is port( clock_in : IN std_logic; --50MHz data_in : IN std_logic_vector(23 downto 0); data_out : OUT std_logic_vector(23 downto 0); adr_in : IN std_logic_vector(17 downto 0); r_w : IN std_logic; enable : IN std_logic; oe : OUT std_logic; bhe : OUT std_logic; ble : OUT std_logic; cs : OUT std_logic; we : OUT std_logic; adr_out : OUT std_logic_vector(17 downto 0); data_inout : INOUT std_logic_vector(23 downto 0) ); end component; component count16bit is port ( clock_in : IN std_logic; enable : IN std_logic; rst : IN std_logic; max : IN std_logic_vector(15 downto 0); carry : OUT std_logic; data : OUT std_logic_vector (15 downto 0) ); end component; signal uart_d : std_logic_vector(7 downto 0); signal uart_ready : std_logic; type states is (s0,s2,start); signal state : states; signal tel : std_logic_vector(17 downto 0); signal mem_data_in : std_logic_vector(23 downto 0); signal mem_data_out : std_logic_vector(23 downto 0); signal mem_adr : std_logic_vector(17 downto 0); signal mem_rw : std_logic; signal mem_en : std_logic; signal mem_data_out_buf : std_logic_vector(23 downto 0); signal vorige_ready : std_logic; signal vorige_ready2 : std_logic; signal byte_count : std_logic_vector(1 downto 0); signal curr_addr : std_logic_vector(17 downto 0);
Page 98 of 127
signal en_rate : std_logic; signal go : std_logic; signal dat_out_buf : std_logic_vector (7 downto 0); signal uart_err : std_logic; signal vorige_err : std_logic; signal vorige_err2 : std_logic; signal timeout : std_logic_vector(20 downto 0); signal len : std_logic_vector(17 downto 0); signal rst_buf : std_logic; constant start_addr : std_logic_vector (17 downto 0) := "000000000000000000"; constant deflen : std_logic_vector(17 downto 0) := "001100100101011110"; begin uart1 : UART port map( dataOut => uart_d, readDataReady => uart_ready, clk => clock_in, rx => rx_in, dataIn=>"00000000", loadData=>'0', rst=>rst, mode=>"10", error=>uart_err ); mem : mem_control port map( clock_in => clock_in, data_in => mem_data_in, data_out => mem_data_out, adr_in => mem_adr, r_w => mem_rw, enable => mem_en, oe => sram_oe, bhe => sram_bhe, ble => sram_ble, cs => sram_cs, we => sram_we, adr_out => sram_adr, data_inout => sram_data );
Page 99 of 127
srate : count16bit port map( clock_in => clock_in, enable => go, rst => '0', max => "0000111110011111", carry => en_rate ); process(clock_in, rst_buf) begin if rst_buf='1' then state<=s0; elsif (clock_in'EVENT and clock_in='1') then vorige_ready<=vorige_ready2; vorige_ready2<=uart_ready; vorige_err<=vorige_err2; vorige_err2<=uart_err; data_out<=dat_out_buf; enable_out<=en_rate; case state is when s0 => dat_out_buf<="00000000"; go<='0'; byte_count<="00"; tel<="000000000000000000"; curr_addr<=start_addr; state <= s2; timeout<="111111111111111111111"; len<=deflen; enable_out<='0';
when s2 => if (uart_ready='1' and vorige_ready='0') then timeout<="111111111111111111111"; vorige_ready<='1'; if tel<=len then --write data to mem if byte_count<2 then mem_en<='0'; if byte_count=0 then mem_data_in(7 downto 0)<=uart_d; else mem_data_in(15 downto 8)<=uart_d; end if; byte_count<=byte_count+1; else mem_data_in(23 downto 16)<=uart_d; byte_count<="00"; mem_en<='1'; mem_rw<='0'; mem_adr<=curr_addr; curr_addr<=curr_addr+1; end if; tel<=tel+1; end if; elsif tel>len or (timeout=0 and tel>0) then state <= start; curr_addr<=start_addr; tel<="000000000000000000"; byte_count<="00"; mem_en<='0'; len<=tel; else mem_en<='0'; if timeout>0 then timeout<=timeout-1; end if; end if;
when start => go<='1'; if en_rate='1' then case byte_count is when "00" => mem_adr<=curr_addr; mem_en<='1'; mem_rw<='1'; dat_out_buf<=mem_data_out_buf(23 downto 16); curr_addr<=curr_addr+1; byte_count<="01"; when "01" => dat_out_buf<=mem_data_out_buf(7 downto 0); byte_count<="10"; when "10" => dat_out_buf<=mem_data_out_buf(15 downto 8); byte_count<="00"; when others => byte_count<="00"; end case; tel<=tel+1; if tel>len then curr_addr<=start_addr; tel<="000000000000000000"; end if; else mem_en<='0'; end if; when others => state <=s0; end case; mem_data_out_buf <= mem_data_out; rst_buf<=rst; end if; end process; end in_arch;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity mem_control is port( clock_in : IN std_logic; --50MHz data_in : IN std_logic_vector(23 downto 0); data_out : OUT std_logic_vector(23 downto 0); adr_in : IN std_logic_vector(17 downto 0); r_w : IN std_logic; enable : IN std_logic; oe : OUT std_logic; bhe : OUT std_logic; ble : OUT std_logic; cs : OUT std_logic; we : OUT std_logic; adr_out : OUT std_logic_vector(17 downto 0); data_inout : INOUT std_logic_vector(23 downto 0) ); end mem_control; architecture mem_arch of mem_control is type states is (s0,s1,s2); signal state : states; begin process(clock_in) begin if (clock_in'EVENT and clock_in='1') then if r_w='1' then --read case state is when s0 => if enable='1' then oe<='0'; bhe<='0'; ble<='0'; cs<='0'; adr_out<=adr_in; state <= s1; else cs<='1'; end if; we<='1'; data_inout<="ZZZZZZZZZZZZZZZZZZZZZ ZZZ";
when s1 => data_out<=data_inout; state <= s2; when s2 => data_inout<="ZZZZZZZZZZZZZZZZZZZZZ ZZZ"; cs<='1'; state <= s0; when others => state <= s0; end case; else --write case state is when s0 => if enable='1' then oe<='0'; bhe<='0'; ble<='0'; cs<='0'; we<='0'; adr_out<=adr_in; state <= s1; data_inout<=data_in; data_out<="000000000000000000000 000"; else data_inout<="ZZZZZZZZZZZZZZZZZZ ZZZZZZ"; cs<='1'; we<='1'; end if; when s1 => state <= s2; cs<='1'; when s2 => data_out<="000000000000000000000000"; data_inout<="ZZZZZZZZZZZZZZZZZZZZZ ZZZ"; we<='1'; state <= s0; when others => state <= s0; end case; end if; end if; end process; end mem_arch;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity UART is port( dataIn : IN std_logic_vector (7 downto 0); loadData : IN std_logic; dataOut : OUT std_logic_vector (7 downto 0); readDataReady : OUT std_logic; busy : OUT std_logic; error : OUT std_logic; clk : IN std_logic; --50MHZ rst : IN std_logic; mode : IN std_logic_vector(1 downto 0); rx : IN std_logic; tx : OUT std_logic ); end UART; architecture UART_arch of UART is component mux port( muxIn : IN std_logic_vector (15 downto 0); sel : IN std_logic_vector (3 downto 0); clkIn : IN std_logic; muxOut : OUT std_logic ); end component; component parity port( parIn : IN std_logic_vector (7 downto 0); clkIn : IN std_logic; calc : IN std_logic; parOut : OUT std_logic ); end component;
component buf port( bufIn : IN std_logic_vector (7 downto 0); clk : IN std_logic; send : IN std_logic; bufOut : OUT std_logic_vector (7 downto 0) ); end component; component UART_writecontrol port( loadData : IN std_logic; wr_busy : OUT std_logic; clkIn : IN std_logic; rstIn : IN std_logic; baud : IN std_logic; shift : OUT std_logic; par : OUT std_logic; mux_sel : OUT std_logic_vector (3 downto 0) ); end component; component UART_readcontrol port( rxIn : IN std_logic; par : IN std_logic; ready : OUT std_logic; err : OUT std_logic; mode : IN std_logic_vector(1 downto 0); clkIn : IN std_logic; baud : IN std_logic; readOut : OUT std_logic_vector (7 downto 0); rst : IN std_logic ); end component; component pll PORT( inclk0 c0 ); end component; : IN STD_LOGIC := '0'; : OUT STD_LOGIC
component count16bit port ( clock_in : IN std_logic; enable : IN std_logic; rst : IN std_logic; max : IN std_logic_vector(15 downto 0); carry : OUT std_logic; data : OUT std_logic_vector (15 downto 0) ); end component; signal data_in_buf : std_logic_vector (7 downto 0); signal parbit : std_logic; signal calc_parity : std_logic := '0'; signal shiftData : std_logic := '0'; signal muxData : std_logic_vector (15 downto 0); signal s_sel : std_logic_vector (3 downto 0) := "1111"; signal readPar : std_logic; signal readReg : std_logic_vector (7 downto 0); signal readReady2 : std_logic; signal readReady : std_logic; signal clk_4800k : std_logic; signal en_38400hz : std_logic; signal clk_sig : std_logic; signal mode_sel : std_logic_vector(2 downto 0); signal baud : std_logic; signal vorige_clk : std_logic; signal rst_buf : std_logic; begin pll1 : pll port map( inclk0 => clk, c0 => clk_4800k ); c0 : count16bit port map( clock_in => clk_4800k, enable => '1', rst => '0', max => "0000000001111100", carry => en_38400hz );
c1 : count16bit port map( clock_in => clk_4800k, enable => en_38400hz, rst => '0', max => ("0000000000000" & mode_sel), carry => clk_sig ); mux1 : mux port map( muxIn => muxData, sel => s_sel, clkIn => clk, muxOut => tx ); parity1 : parity port map( parIn => data_in_buf, clkIn => clk, calc => calc_parity, parOut => parbit ); buf1 : buf port map( bufIn => dataIn, clk => clk, send => shiftData, bufOut => data_in_buf ); write1 : UART_writecontrol port map( loadData => loadData, wr_busy => busy, clkIn => clk, rstIn => rst, shift => shiftData, par => calc_parity, mux_sel => s_sel, baud=>baud );
read1 : UART_readcontrol port map( rxIn => rx, par => readPar, ready => readReady2, err => error, clkIn => clk, readOut => readReg, baud=>baud, mode => mode, rst => rst_buf ); parity2 : parity port map( parIn => readReg, clkIn => clk, calc => clk, parOut => readPar ); muxData <= "10" & data_in_buf & parbit & "00000"; process(clk) begin if (clk'EVENT and clk='1') then if readReady='0' and readReady2='1' then dataOut<=readReg; end if; if (clk_sig='1' and vorige_clk='0' and mode/="11") or (en_38400hz='1' and vorige_clk='0' and mode="11") then case mode is when "10" => mode_sel<="001"; baud <= clk_sig; when "01" => mode_sel<="011"; baud <= clk_sig; when "00" => mode_sel<="111"; baud <= clk_sig; when others => mode_sel<="000"; baud <= en_38400hz; end case; else baud<='0'; end if; if mode="11" then vorige_clk<=en_38400hz; else vorige_clk<=clk_sig; end if;
readDataReady<=readReady2; readReady<=readReady2; rst_buf<=rst; end if; end process; end UART_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity UART_writecontrol is port( loadData : IN std_logic; wr_busy : OUT std_logic; clkIn : IN std_logic; rstIn : IN std_logic; baud : IN std_logic; shift : OUT std_logic; par : OUT std_logic; mux_sel : OUT std_logic_vector (3 downto 0) ); end UART_writecontrol; architecture UART_wc_arch of UART_writecontrol is type state is (idle,load,start,d0,d1,d2,d3,d4,d5,d6,d7,pari,stop); signal toestand : state; signal vorige_loadData : std_logic := '0'; begin process(clkIn, rstIn) begin if rstIn='1' then toestand <= idle; mux_sel <= "1111"; elsif (clkIn'EVENT and clkIn='1') then if baud='1' then
case toestand is when idle => if loadData='1' and vorige_loadData='0' then toestand <= load; wr_busy <= '1'; else wr_busy <= '0'; end if; shift <= '0'; par <= '0'; mux_sel <= "1111"; vorige_loadData <= loadData; when load => shift <= '1'; toestand <= start; when start => shift <= '0'; par <= '1'; mux_sel <= "1110"; toestand <= d0; when d0 => par <= '0'; mux_sel <= "0110"; toestand <= d1; when d1 => mux_sel <= "0111"; toestand <= d2; when d2 => mux_sel <= "1000"; toestand <= d3; when d3 => mux_sel <= "1001"; toestand <= d4; when d4 => mux_sel <= "1010"; toestand <= d5; when d5 => mux_sel <= "1011"; toestand <= d6; when d6 => mux_sel <= "1100"; toestand <= d7; when d7 => mux_sel <= "1101"; toestand <= pari;
when pari => mux_sel <= "0101"; toestand <= stop; when stop => mux_sel <= "1111"; wr_busy <= '0'; toestand <= idle; when others => toestand <= idle; mux_sel <= "1111"; end case; elsif toestand=idle then mux_sel <= "1111"; end if; end if; end process; end UART_wc_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity UART_readcontrol is port( rxIn : IN std_logic; par : IN std_logic; ready : OUT std_logic; err : OUT std_logic; mode : IN std_logic_vector(1 downto 0); clkIn : IN std_logic; baud : IN std_logic; readOut : OUT std_logic_vector (7 downto 0); rst : IN std_logic ); end UART_readcontrol; architecture UART_rc_arch of UART_readcontrol is type state is (idle,wacht1,sample,wacht,check); signal toestand : state; signal offset : std_logic_vector(13 downto 0); signal max_offset : std_logic_vector(13 downto 0); signal clk_div : std_logic_vector(14 downto 0); signal parity : std_logic;
signal vorige_rxIn : std_logic; signal vorige2_rxIn : std_logic; signal rxIn_b : std_logic; signal samples : std_logic_vector(3 downto 0); signal sample_count : std_logic_vector(2 downto 0); signal sample_offset : std_logic_vector(5 downto 0); signal bit_count : std_logic_vector(3 downto 0); signal huidig_offset : std_logic_vector(12 downto 0); constant o_4800 : std_logic_vector(12 downto 0):="1010000011001"; constant o_9600 : std_logic_vector(12 downto 0):="0100111011000"; constant o_19200 : std_logic_vector(12 downto 0):="0010010110111"; constant o_38400 : std_logic_vector(12 downto 0):="0001000100010"; begin process(clkIn, rst) begin if rst='1' then toestand<=idle; elsif (clkIn'EVENT and clkIn='1') then vorige_rxIn<=vorige2_rxIn; vorige2_rxIn<=rxIn_b; rxIn_b<=rxIn; case toestand is when idle => if baud='1' then max_offset<=offset; offset<="00000000000000"; else offset<=offset+1; end if; case mode is when "00" => huidig_offset <= o_4800; when "01" => huidig_offset <= o_9600; when "10" => huidig_offset <= o_19200; when "11" => huidig_offset <= o_38400; end case; if rxIn_b='0' and vorige_rxIn='1' then toestand<=wacht1; end if;
when wacht1 => ready<='0'; err<='0'; if baud='1' then clk_div<=(('0' & offset)+("00" & huidig_offset)); sample_count<="000"; sample_offset<="000000"; bit_count<="0000"; toestand<=sample; end if; when sample => if clk_div=0 or sample_count>0 then if sample_offset=0 then sample_offset<="101010"; sample_count<=sample_count+1; case sample_count is when "000" => samples(0) <= vorige_rxIn; when "001" => samples(1) <= vorige_rxIn; when "010" => samples(2) <= vorige_rxIn; when "011" => samples(3) <= vorige_rxIn; when others => if (("00" & samples(0)) + ("00" & samples(1)) + ("00" & samples(2)) + ("00" & samples(3)) + ("00" & vorige_rxIn))>2 then case bit_count is when "0000" => readOut(0) <= '1'; when "0001" => readOut(1) <= '1'; when "0010" => readOut(2) <= '1'; when "0011" => readOut(3) <= '1'; when "0100" => readOut(4) <= '1'; when "0101" => readOut(5) <= '1'; when "0110" => readOut(6) <= '1'; when "0111" => readOut(7) <= '1';
when others => parity <= '1'; end case; else case bit_count is when "0000" => readOut(0) <= '0'; when "0001" => readOut(1) <= '0'; when "0010" => readOut(2) <= '0'; when "0011" => readOut(3) <= '0'; when "0100" => readOut(4) <= '0'; when "0101" => readOut(5) <= '0'; when "0110" => readOut(6) <= '0'; when "0111" => readOut(7) <= '0'; when others => parity <= '0'; end case; end if; if bit_count<8 then if clk_div=0 then toestand<=wacht; else sample_count<="000"; sample_offset<="000000"; bit_count<=bit_count+1; end if; else toestand<=check; end if; end case; else sample_offset<=sample_offset-1; end if; end if;
if baud='1' then if (offset+('0' & huidig_offset))>=max_offset then clk_div<=((('0' & offset)+ ("00" & huidig_offset))-('0' & max_offset)); else clk_div<=(('0' & offset)+("00" & huidig_offset)); end if; end if; if clk_div>0 then clk_div<=clk_div-1; end if; when wacht => if baud='1' or clk_div>0 then if (offset+('0' & huidig_offset))>=max_offset then clk_div<=((('0' & offset)+ ("00" & huidig_offset))-('0' & max_offset)); else clk_div<=(('0' & offset)+("00" & huidig_offset)); end if; sample_count<="000"; sample_offset<="000000"; bit_count<=bit_count+1; toestand<=sample; end if; when check => if par=parity then ready <= '1'; err <= '0'; else err <= '1'; ready <= '0'; end if; if (offset+('0' & huidig_offset)+"11010") >=max_offset then offset<=((offset+('0' & huidig_offset)+"11010")max_offset); else offset<=(offset+('0' & huidig_offset)+"11010"); end if; toestand <= idle; when others => toestand <= idle; end case; end if; end process; end UART_rc_arch;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity EQ_effect is port( clock_in : IN std_logic; --50MHz data_in : IN std_logic_vector(7 downto 0); data_out : OUT std_logic_vector(7 downto 0); enable : IN std_logic; amp0 : IN std_logic_vector(2 downto 0); amp1 : IN std_logic_vector(2 downto 0); amp2 : IN std_logic_vector(2 downto 0); amp3 : IN std_logic_vector(2 downto 0) ); end EQ_effect; architecture EQ_effect_arch of EQ_effect is component FIR is port( clock_in : IN std_logic; --50MHz enable : IN std_logic; data_in : IN std_logic_vector(7 downto 0); data_out : OUT std_logic_vector(17 downto 0); c0 : IN std_logic_vector(7 downto 0); c1 : IN std_logic_vector(7 downto 0); c2 : IN std_logic_vector(7 downto 0); c3 : IN std_logic_vector(7 downto 0); c4 : IN std_logic_vector(7 downto 0); c5 : IN std_logic_vector(7 downto 0); c6 : IN std_logic_vector(7 downto 0); c7 : IN std_logic_vector(7 downto 0); c8 : IN std_logic_vector(7 downto 0); c9 : IN std_logic_vector(7 downto 0); c10 : IN std_logic_vector(7 downto 0); c11 : IN std_logic_vector(7 downto 0); c12 : IN std_logic_vector(7 downto 0); c13 : IN std_logic_vector(7 downto 0); c14 : IN std_logic_vector(7 downto 0); c15 : IN std_logic_vector(7 downto 0) ); end component;
component gain is port( clock_in : IN std_logic; --50MHz enable : IN std_logic; data_in : IN std_logic_vector(7 downto 0); data_out : OUT std_logic_vector(7 downto 0); amount : IN std_logic_vector(2 downto 0) ); end component; signal fir0_out : std_logic_vector(17 downto 0); signal fir1_out : std_logic_vector(17 downto 0); signal fir2_out : std_logic_vector(17 downto 0); signal fir3_out : std_logic_vector(17 downto 0); signal db0_out : std_logic_vector(7 downto 0); signal db1_out : std_logic_vector(7 downto 0); signal db2_out : std_logic_vector(7 downto 0); signal db3_out : std_logic_vector(7 downto 0); signal in_buf0 : std_logic_vector(7 downto 0); signal in_buf1 : std_logic_vector(7 downto 0); signal in_buf2 : std_logic_vector(7 downto 0); signal in_buf3 : std_logic_vector(7 downto 0); begin fir0 : FIR port map( clock_in => clock_in, enable => enable, data_in => in_buf0, data_out => fir0_out, c0 =>"00000101", c1 =>"00001000", c2 =>"00010000", c3 =>"00011100", c4 =>"00101010", c5 =>"00110111", c6 =>"01000001", c7 =>"10000111", c8 =>"10000111", c9 =>"01000001", c10 =>"00110111", c11 =>"00101010", c12 =>"00011100", c13 =>"00010000", c14 =>"00001000", c15 =>"00000101" );--*32
fir1 : FIR port map( clock_in => clock_in, enable => enable, data_in => in_buf1, data_out => fir1_out, c0 =>"00000001", c1 =>"00000011", c2 =>"00001001", c3 =>"00010101", c4 =>"00100110", c5 =>"00111001", c6 =>"01001010", c7 =>"01010011", c8 =>"01010011", c9 =>"01001010", c10 =>"00111001", c11 =>"00100110", c12 =>"00010101", c13 =>"00001001", c14 =>"00000011", c15 =>"00000001" );--*8 fir2 : FIR port map( clock_in => clock_in, enable => enable, data_in => in_buf2, data_out => fir2_out, c0 =>"00000000", c1 =>"11111110", c2 =>"11111100", c3 =>"00000000", c4 =>"11110011", c5 =>"11010111", c6 =>"00000001", c7 =>"01100010", c8 =>"01100010", c9 =>"00000001", c10 =>"11010111", c11 =>"11110011", c12 =>"00000000", c13 =>"11111100", c14 =>"11111110", c15 =>"00000000" );--*2 fir3 : FIR port map( clock_in => clock_in, enable => enable, data_in => in_buf3, data_out => fir3_out, c0 =>"00000000", c1 =>"00000001", c2 =>"11111110", c3 =>"11111010", c4 =>"00001110", c5 =>"00001100", c6 =>"10110100", c7 =>"01110000", c8 =>"10110100", c9 =>"00001100", c10 =>"00001110", c11 =>"11111010", c12 =>"11111110", c13 =>"00000001", c14 =>"00000000", c15 =>"00000000" );--*2
db0 : gain port map( clock_in => clock_in, enable => enable, data_in => "0000" & fir0_out(17 downto 14), data_out => db0_out, amount => amp0 ); db1 : gain port map( clock_in => clock_in, enable => enable, data_in => "000" & fir1_out(17 downto 13), data_out => db1_out, amount => amp1 ); db2 : gain port map( clock_in => clock_in, enable => enable, data_in => fir2_out(16 downto 9), data_out => db2_out, amount => amp2 ); db3 : gain port map( clock_in => clock_in, enable => enable, data_in => fir3_out(16 downto 9), data_out => db3_out, amount => amp3 );
process(clock_in) begin if (clock_in'EVENT and clock_in='1') then data_out<=db0_out+db1_out+db2_out+db3_out; in_buf0<=data_in; in_buf1<=data_in; in_buf2<=data_in; in_buf3<=data_in; end if; end process; end EQ_effect_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_signed.all; entity FIR is port( clock_in : IN std_logic; --50MHz enable : IN std_logic; data_in : IN std_logic_vector(7 downto 0); data_out : OUT std_logic_vector(17 downto 0); c0 : IN std_logic_vector(7 downto 0); c1 : IN std_logic_vector(7 downto 0); c2 : IN std_logic_vector(7 downto 0); c3 : IN std_logic_vector(7 downto 0); c4 : IN std_logic_vector(7 downto 0); c5 : IN std_logic_vector(7 downto 0); c6 : IN std_logic_vector(7 downto 0); c7 : IN std_logic_vector(7 downto 0); c8 : IN std_logic_vector(7 downto 0); c9 : IN std_logic_vector(7 downto 0); c10 : IN std_logic_vector(7 downto 0); c11 : IN std_logic_vector(7 downto 0); c12 : IN std_logic_vector(7 downto 0); c13 : IN std_logic_vector(7 downto 0); c14 : IN std_logic_vector(7 downto 0); c15 : IN std_logic_vector(7 downto 0) ); end FIR;
architecture FIR_arch of FIR is signal d0 : std_logic_vector(7 downto 0); signal d1 : std_logic_vector(7 downto 0); signal d2 : std_logic_vector(7 downto 0); signal d3 : std_logic_vector(7 downto 0); signal d4 : std_logic_vector(7 downto 0); signal d5 : std_logic_vector(7 downto 0); signal d6 : std_logic_vector(7 downto 0); signal d7 : std_logic_vector(7 downto 0); signal d8 : std_logic_vector(7 downto 0); signal d9 : std_logic_vector(7 downto 0); signal d10 : std_logic_vector(7 downto 0); signal d11 : std_logic_vector(7 downto 0); signal d12 : std_logic_vector(7 downto 0); signal d13 : std_logic_vector(7 downto 0); signal d14 : std_logic_vector(7 downto 0); signal d15 : std_logic_vector(7 downto 0); signal sum1 : std_logic_vector(17 downto 0); signal sum2 : std_logic_vector(17 downto 0); begin process(clock_in) begin if (clock_in'EVENT and clock_in='1') then if enable='1' then d0<=data_in; d1<=d0; d2<=d1; d3<=d2; d4<=d3; d5<=d4; d6<=d5; d7<=d6; d8<=d7; d9<=d8; d10<=d9; d11<=d10; d12<=d11; d13<=d12; d14<=d13; d15<=d14;
sum1<=(c0*("00" & d0)) + (c1*("00" & d1)) + (c2*("00" & d2)) + (c3*("00" & d3)) + (c4*("00" & d4)) + (c5*("00" & d5)) + (c6*("00" & d6)) + (c7*("00" & d7)); sum2<=(c8*("00" & d8)) + (c9*("00" & d9)) + (c10*("00" & d10)) + (c11*("00" & d11)) + (c12*("00" & d12)) + (c13*("00" & d13)) + (c14*("00" & d14)) + (c15*("00" & d15)); else if (sum1+sum2)<0 then data_out<="000000000000000000"; else data_out<=(sum1+sum2); end if; end if; end if; end process; end FIR_arch; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity gain is port( clock_in : IN std_logic; --50MHz enable : IN std_logic; data_in : IN std_logic_vector(7 downto 0); data_out : OUT std_logic_vector(7 downto 0); amount : IN std_logic_vector(2 downto 0) ); end gain;
architecture gain_arch of gain is begin process(clock_in) begin if (clock_in'EVENT and clock_in='1') then if enable='1' then case amount is when "000" => data_out <= data_in; when "001" => data_out <= '0' & data_in(7) & data_in(6) & data_in(5) & data_in(4) & data_in(3) & data_in(2) & data_in(1); when "010" => data_out <= "00" & data_in(7) & data_in(6) & data_in(5) & data_in(4) & data_in(3) & data_in(2); when "011" => data_out <="000" & data_in(7) & data_in(6) & data_in(5) & data_in(4) & data_in(3); when "100" =>data_out<="0000" & data_in(7) & data_in(6) & data_in(5) & data_in(4); when "101" => data_out <= "00000" & data_in(7) & data_in(6) & data_in(5); when "110" => data_out <= "000000" & data_in(7) & data_in(6); when "111" => data_out <= "0000000" & data_in(7); end case; end if; end if; end process; end gain_arch;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity PWM is port( clock_in : IN std_logic; --50MHz data_in : IN std_logic_vector(7 downto 0); pwm_out : OUT std_logic ); end PWM; architecture PWM_arch of PWM is signal tel : std_logic_vector(7 downto 0):="00000000"; begin process(clock_in) begin if (clock_in'EVENT and clock_in='1') then if data_in<=tel then pwm_out<='0'; else pwm_out<='1'; end if; tel<=tel+1; end if; end process; end PWM_arch; VISUAL BASIC CODE: Private Sub cmd_load_Click() Dim FileNr As Integer Dim i As Long Dim Data As Integer Dim str As String Dim a cmd.Caption = "Data transfer..." DoEvents uart.PortOpen = True FileNr = FreeFile Open "data.dat" For Input As FileNr Line Input #FileNr, str Close FileNr
a = Split(str, vbLf) i=0 On Error GoTo einde Do While a(i) <> "" Do While uart.CommEvent = comEventTxFull DoEvents Loop uart.Output = Chr(a(i)) i=i+1 Loop einde: On Error GoTo 0 cmd.Caption = "Finished!" uart.PortOpen = False End Sub
XIII. References
http://www.altera.com (Altera official site) http://www.xilinx.com (Xilinx official site) http://www.digilentinc.com (Xilinx I/O board) http://www.fpga.nl (Altera Audio/VGA board) http://home.iae.nl/users/pouweha/lcd/lcd.shtml (LCD displays) http://emsys.denayer.wenk.be (Embedded Systems research group)