I have a Spartan 3E kit. In that kit 4 switches are there, 4 push buttons are there.
For my thesis I require 16 bit input but I convert to 8 bit.
Now my problem is I have 4 switches i can give input only 4 bits,and other 4 bits with out using push button how can I give input.
Advance thanks if any one have any idea how can I give extra 4 bits using external interface,
using Spartan 3E kit.
You have a ton of options available to you:
http://www.xilinx.com/support/documentation/boards_and_kits/ug230.pdf
Obviously you have the built in buttons and switches you mentioned, and there is a rotary push button, which you could use. Here are some other options that aren't fully built in but you could easily make use of (with the least difficult options first):
The 43 I/Os coming from the Hirose 100-pin FX2 Edge Connector, you could hook additional buttons/switches up to these I/Os. Then write VHDL to monitor the I/O just as you would the built in buttons/switches.
RS-232 Serial ports, plug it into a serial port on a PC and open up a terminal program to talk to it, and see what happens. Again another vhdl block is required to get it to work, but here is a start on that:
http://forums.xilinx.com/t5/Xilinx-Boards-and-Kits/Rs232-port-on-Spartan-3-starter-board/td-p/19282
PS/2 keyboard port, you could plug a keyboard in, again you would need to add some vhdl logic to actually read the keyboard as demonstrated here:
http://www.youtube.com/watch?v=aZeutF6d0Z4
10/100 Ethernet Physical Layer Interface, you could talk to it over ethernet, looks like the MAC is available as part of the EDK Platform Studio’s Base System Builder, and you can write code on a MicroBlaze softcore to talk ethernet!
If you don't need to be able to adjust the input quickly, you can simply use the pushbuttons to latch the switches into their own 4-bit part of your vector. For instance (to read in a 16-bit vector):
process(clk)
begin
if(rising_edge(clk)) then
case pushbuttons is
when "0001" =>
data(15 downto 12) <= switches;
when "0010" =>
data(11 downto 8) <= switches;
when "0100" =>
data(7 downto 4) <= switches;
when "1000" =>
data(3 downto 0) <= switches;
when others =>
end case;
end if;
end process;
If you only need 8-bit input, just chop off the top-half of the case-statement.
Related
I want to design a IIC sniffer in VHDL and I struggle at a very basic point.
To keep it "sequential" I want to set a flag after every part that will be executed by an entity.
Now I want to set a Flag on the START condition (SCL = HIGH & RISING_EDGE on SDA)
This flag should be resetted on the STOP condition (SCL = HIGH & FALLING_EDGE on SDA) and when I push a reset button.
I now have the problem that I can not get the flag to be set by the START and resetted by the STOP command.
How should I approach to get a flag for this period?
entity scltest is
port( scl, sda: in std_logic;
scled, sdaled, flag: out std_logic
);
end scltest;
architecture test of scltest is
begin
scled <= scl;
sdaled <= sda;
process(sda)
begin
if (scl = '1' AND rising_edge(sda)) then
flag <= '1';
else
if (scl = '1' AND falling_edge(sda)) then
flag <= '0';
end if;
end if;
end process;
end test;
This code does not work because:
"Error (10820): Netlist error at scltest.vhd(18): can't infer register for flag because its behavior depends on the edges of multiple distinct clocks"
I do understand why it won't work but I can't think of a design that will work which gives me the same function.
Thank you in advance.
Your basic idea seems to be that you want to do all your logic with the bus clock. However, your design shouldn't depend entirely on the bus clocks -- especially since I²C is so slow.
You'll want to have a running system that can do other tasks (like USB, USART...) to report to your host system (PC, SoC...) about the state of the I²C bus.
Towards that end, you'll need to sample both SCL and SDA and have a core clocked by your system clock perform the actual anaylsis of rising/fallig edges, bus states etc. That way, all your logic will be synchronous to your system clock.
Depending on your development board, example designs might exist that already have the host side ready and you would only need to "plug" your module in the right place. A good starting point IMHO1 would be one of Digilent's Spartan boards as the host side code is freely available with tools and a programming API.
1 I'm not affiliated with Digilent in any way.
This is probably more of an iCEstick question than a yosys one, but asking here since I'm using the Icestorm tool chain.
I want to specify startup behavior of my design, which various places on the internet seem to agree is related to the typically named rst signal. It wasn't obvious to me where such a signal comes from, so I dug into the powerup sequence. Current understanding is from Figure 2 in this document.
After CDONE is pulled high by the device, all of the internal registers have been reset, to some initial value. Now, I've found plenty of lattice documents about how each type of flip-flop or hard IP receives a reset signal and does something with its internal state, but I still don't quite understand how I specify what those states are (or even just know what they are so I can use them).
For example, if I wanted to bring an LED high for 1 second after powerup (and only after powerup) I would want to start a counter after this reset signal (whatever it is) disables.
Poking around the ice40 family data sheet and the Lattice site, I found this document about using the Global Set/Reset signal. I confirmed this GSR is mentioned in the family data sheet, referenced on page 2-3 under "Clock/Control Distribution Network". It seems that a global reset signal is usable by one of the global buffers GBUF[0-7] and can be routed (up to 4 of them) to all LUTs with the global/high-fanout distribution network.
This seems like exactly what I was after, I but I can't find any other info about how to use this in my designs. The document on using the GSR states that you can instantiate a native GSR component like this:
GSR GSR_INST (.GSR (<global reset sig>));
but I can't tell whether this is just for simulation. Am I completely going in the wrong direction here or just missing something? I'm very inexperienced with FPGAs and hardware, so its entirely possible my entire approach is flawed.
I'm not sure if that GSR document actually is about iCE40. The Lattice iCEcube tool interestingly accepts instances of GSR cells, but it seems to simply treat them as constant zero drivers. There is also no simulation model for the GSR cell type in the iCE40 sim library and no description of it in the iCE40 tech library documentation provided by Lattice.
Furthermore, I have built the following two designs with the lattice tools, and besides the timestamp in the "comment field" of the generated bit-stream file, the generated bit-streams are identical! (This test was performed with Lattice LSE as synthesis tool, not Synplify. I had problems getting Synplify to run on my machine for some reason and gave up trying to do so over a year ago..)
This is the first test design I've used:
module top (
input clk,
output rst,
output reg val
);
always #(posedge clk, posedge rst)
if (rst)
val = 1;
else
val = 0;
GSR GSR_INST (.GSR (rst));
endmodule
And this is the second test design:
module top (
input clk,
output rst,
output val
);
assign val = 0, rst = 0;
endmodule
Given this results I think it is safe to say that the lattice tools simply ignore GSR cells in iCE40 designs. (Maybe for compatibility with their other FPGA families?)
So how does one generate a rst signal then? For example, the following is a simple reset generator that asserts (pulls low) resetn for the first 15 cycles:
input clk;
...
wire resetn;
reg [3:0] rststate = 0;
assign resetn = &rststate;
always #(posedge clk) rststate <= rststate + !resetn;
(The IceStorm flow does support arbitrary initialization values for registers, whereas the lattice tools ignore the initialization value and simply initialize all FFs to zero. So if you want your designs to be portable between the tools, it is recommended to only initialize regs to zero.)
If you are using a PLL, then it is custom to use the PLL LOCK output to drive the resetn signal. Unfortunately the "iCE40 sysCLOCK PLL Design and Usage Guide" does not state if the generated LOCK signal is already synchronous to the generated clock, so it would be a good idea to synchronize it to the clock to avoid problems with metastability:
wire clk, resetn, PLL_LOCKED;
reg [3:0] PLL_LOCKED_BUF;
...
SB_PLL40_PAD #( ... ) PLL_INST (
...
.PLLOUTGLOBAL(clk),
.LOCK(PLL_LOCKED)
);
always #(posedge clk)
PLL_LOCKED_BUF <= {PLL_LOCKED_BUF, PLL_LOCKED};
assign resetn = PLL_LOCKED_BUF[3];
Regarding usage of global nets: You can explicitly route the resetn signal via a global net (using the SB_GB primitive), but using the IceStorm flow, arachne-pnr will automatically route a set/reset signal (when used by more than just a few FFs) over a global net, if a global net is available.
I know what the inout parameters is and how to use them. Assume that we have an inout parameter io and want to create a bidirectional static RAM such as the following code :
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY sram IS
port(
clk : IN std_logic;
wr : IN std_logic;
io : INOUT std_logic;
addr : IN INTEGER RANGE 0 TO 7
);
END sram;
ARCHITECTURE behavioral OF sram IS
TYPE matrix IS ARRAY (0 TO 7) OF std_logic;
SIGNAL mem : matrix;
BEGIN
PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF wr = '1' THEN
mem(addr) <= io;
END IF;
END IF;
END PROCESS;
io <= mem(addr) WHEN wr = '0' ELSE 'Z';
END behavioral;
We can create an instance of sram and write on it such as the following code :
io <= '1' WHEN wr = '1' ELSE 'Z';
Question : How can synthesis tool control the multiple assignments and judge between multiple drivers ? What hardware is implemented to do it ?
Thanks for comments and answers ...
For typical FPGA and ASIC devices, implementation of tristate capabilities are only available on the IO, like for example in an Altera Arria 10 FPGA:
So for such devices, the internal RAMs are always implemented with dedicated input and output ports, thus not using any internal tristate capabilities.
Even if a RAM is connected to external IOs that support tristate, then the internal RAM block is still typically created with dedicated input and output ports, so the connection to a tristate capable pin on the device is handled through an in-out buffer with the output enable and tristate capability.
If internal design tries to use tristate capabilities or multiple drivers when this is not supported by the device, then the synthesis tool will generate and error, typically saying that multiple drivers are not supported for the same net.
On Xilinx devices, the schematics are similar.
This is an image of primitive IOBUF:
The green part is the output driver with tristate control; the blue part is the input driver. The complete IOB (Input/Output Block) consists of several primitives:
IOB registers (input, output, tristate control)
delay chains
wires to combine two IOBs to a differential IOB (**BUFDS)
capability to drive clock networks (CC-IOB - clock capable IOB)
pullup, pulldown, ...
driver (IOBUF)
pin/ball (IPAD, OPAD, IOPAD) - this includes ESD protection
How does synthesis work?
Xilinx synthesis tools (XST / Synth) add IPAD or OPAD primitives for every wire in your top-level component's port description. A pad is just the primitive to represent a physical pin or ball under the FPGA package.
If you enabled to automatically add I/O buffers, the tool will add IBUF, OBUF, IOBUF, IBUFDS, ... primitives between every PAD and top-level port. It uses the port direction (in, out, inout) to infer the correct buffer type. If this option is disabled (default = on) you have to manually add buffers for every I/O pin. In some cases XST gets offended: I added some IOBUFs with tristate control by hand so XST declined to infer the missing buffers. So I had to add all buffers by hand ...
While using Xilinx XST it's possible to use tristate buses (port direction = inout) beneath the top-level. XST will report that it added (virtual) tristate buffers. These buffers get trimmed if the direction of each bit of the bus has an obvious direction and no multiple driver problem.
This does not work in iSim.
I wanted to ask if it is possible to use an inout pin as inout and normal out? The two behaviours should be switched through a MUX. The reason for this weird looking implementation is that I have two boards and I want to use the same bitstream. On one board, the same pin is connected to a LED through GPIO and on the other it goes to my I2C bus connection. The software tries to detect the I2C and if successful it sets a register. If not, it clears it.
LED_or_SDA : inout std_logic; -- port definition
process (register)
begin
if ( register = '1') then -- software sets this register
LED_or_SDA <= I2C_SDA; -- here I want to use it as inout
else
LED_or_SDA <= gpio_reg; -- here I want to use it as normal out
end if;
end process;
This implementation throws the error "bidirect pad net is driving non-buffer primitives" during translate. Is there a solution for this?
No, you can't. A mux is not a switch, it is a logic function. The line
LED_or_SDA <= I2C_SDA;
strongly drives LED_or_SDA from I2C_SDA. It does not connect the two nets in a way that allows bidirectional data flow.
You'll need to separate the two directions:
I2C_SDA_in <= LED_or_SDA;
LED_or_SDA <= gpio_reg WHEN (register = '1') ELSE
'0' WHEN (I2C_SDA_out = '0') ELSE
'Z';
Most I2C logic blocks have separate data in and out signals anyway, right up until the external interface, where you'll find a tri-state buffer expressed in much the same way as the code I gave you. You'll simply need to make the input and output data separate ports on your I2C block.
Unfortunately, the weak drive state of the internal signal likely isn't accessible to internal logic, so these won't work:
LED_or_SDA <= gpio_reg WHEN (register = '1') ELSE
I2C_SDA_out;
LED_or_SDA <= gpio_reg WHEN (register = '1') ELSE
'Z' WHEN (I2C_SDA_out = 'Z') ELSE
I2C_SDA_out;
The VHDL compiler actually is keeping track of a tri-state control signal, and propagating that through port statements until it hits the external pin and connects it to the real (hardware) tri-state buffer. But in most compilers you can't access that control signal for your own logic.
Guessing from your error message I assume that we are talking about a Xilinx System, e.g. around a Microblaze - if that's not the case, please update your question and also specify the exact GPIO core you're using.
Often these GPIO blocks already contain the IO-Buffer macro by default. This IOBUF is located next to a physical pin and can not drive any other signals on the FPGA. Hence the GPIO block is intended to be used on the top level of the chip and be directly connected to a pin. However, there usually is a way to also access the signals before the IOBUF: E.g. in Xilinx Platform Studio on the tab "Ports" you should have a choice to use also GPIO_IO (after buffer), GPIO_IO_I (pure input), GPIO_IO_O (pure output), GPIO_IO_T (tristate) or similar.
Yes, the trick is to treat it always as a tristate buffer, and control the output based on the state of register
-- define a tristate pin the usual way.
LED_or_SDA <= LED_or_SDA_out when LED_or_SDA_tristate = '0' else 'Z';
LED_or_SDA_in <= LED_or_SDA
-- then control the data onto it, and the tristate control line
LED_or_SDA_tristate <= '0' when register = '0' else ICD_SDA;
LED_or_SDA_out <= gpio_reg when register = '0' else '0';
I am making some kind of cache and i am using some tables (big ones) inside entity which are composed of std_logic_vectors and i am doing it in Quartus 2 web edition.
Everything works fine in simulation, but when i try to synthesize it its being done ONLY with latches, AND and OR components.
Is there any way to specify Quartus to use memory modules for those tables instead of these combination elements? Or maybe something can be done from VHDL code itself.
library ieee;
use ieee.std_logic_1164.all;
package UTIL_PACK is
type matrix16x8 is array (0 to 15) of std_logic_vector(0 to 7);
type matrix2p4x8 is array (0 to 2**4) of matrix16x8;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.util_pack.all;
entity RAM16B is
port(
signal RD: in std_logic;
signal WR: in std_logic;
signal CLK: in std_logic;
signal A: in std_logic_vector(7 downto 0);
signal D: inout matrix16x8;
signal FC: out std_logic
);
end entity ;
architecture RAM16B_IMPL of RAM16B is
signal memory: matrix2p4x8 := ((others => (others => (others => 'Z'))));
begin
run:process(clk)is
variable slot:integer range 0 to 15 :=0;
begin
if(clk='1') then
slot := TO_INTEGER(unsigned(A)) rem 16;
if(rd = '1')then
FC<='0';
for i in 0 to 3 loop
D(i) <= memory(i)(slot);
end loop;
FC<='1';
elsif(wr = '1')then
FC<='0';
for i in 0 to 3 loop
memory(i)(slot) <= D(i);
end loop;
FC<='1';
else
FC <= 'Z';
D <= ( others => ( others => 'Z' ));
end if;
else
FC <= 'Z';
D <= ( others => ( others => 'Z' ));
end if;
end process;
end architecture RAM16B_IMPL;
RAM consists of 16 blocks of memory, each block is 16 bytes. I am trying to read more data parallely so I am reading/writing 16 bytes of data per cycle. Slot defines block in which reading/writing is being done.
If you really want to make sure you use the hard memory blocks, you should either use the mega-function wizard to craft a custom ram component, or directly instantiate an altsyncram component from the library and use the generics to configure it how you want (this can be tricky if you're not extremely familiar with the options). This causes porting issues, but any time you infer ram you generally have porting issues anyway. Using a custom library component just makes it very obvious and easy to identify where you might have problems if you ever do need to migrate to something else.
As for your specific implementation, there's no way you're going to get latches automatically migrated into the hard ram blocks which are edge driven devices. Use rising_edge(clk) instead of clk='1' in your process to fix this.
Also, there is no support for tri-state operation internal to the chip, you need independent data in and data out ports. You are getting lots of discrete logic because and & or gates are being used to emulate a tri-state bus (and because of the latch issue, above).
Yes, you can do it from your VHDL code. To make sure that Quartus understands that you are modeling a memory, you should code it as described in Altera's Recommended HDL Coding Styles guide. Take a look at the section called Inferring Memory Functions from HDL Code (http://www.altera.com/literature/hb/qts/qts_qii51007.pdf), then modify your code accordingly.
It is probably a good idea to start with the exact memory model suggested by Altera, and making sure that Quartus synthesizes the design using the FPGA's dedicated memory bits. Next, you can gradually change your model to implement the desired behavior, always synthesizing and looking at the compilation reports to make sure your changes didn't deviate from what Quartus infers as a memory block.