Configuring LED pins as input on MACHxo2 board - input

I am attempting to configure the pins connected to the on board LEDs as input pins. Documentation states they are free i/o, but when I probe them with a scope it says they are outputting a "high" signal. This is on the MACHXO2 7000he cpld, but I assume the answer would be the same for any of the MACH boards.
Thanks in advance for any help.

Hey guys sorry for taking so long to reply. I would attach a picture of the circuit but I currently have too low a reputation to do so.
The LEDs are connected to a VCC of 3.3V. What I found was that by de-soldering the LEDs from the board, I was free to use the pins they were connected to as free i/o because this would create an open circuit between the pins and the 3.3V.
The pins are supposed to already by free i/o but the LEDs were active low which caused my program to see them as high signals all the time, ultimately making these pins permanent outputs.
Anyway, there's my answer and I hope it makes sense and helps one of you out one of these days.
Thanks for the responses.

You could try a led blinking example, like for example this:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY lattice;
USE lattice.components.all;
ENTITY blinking_led IS
PORT(
led : BUFFER STD_LOGIC);
END blinking_led;
ARCHITECTURE behavior OF blinking_led IS
SIGNAL clk : STD_LOGIC;
--internal oscillator
COMPONENT OSCH
GENERIC(
NOM_FREQ: string := "53.20");
PORT(
STDBY : IN STD_LOGIC;
OSC : OUT STD_LOGIC;
SEDSTDBY : OUT STD_LOGIC);
END COMPONENT;
BEGIN
--internal oscillator
OSCInst0: OSCH
GENERIC MAP (NOM_FREQ => "53.20")
PORT MAP (STDBY => '0', OSC => clk, SEDSTDBY => OPEN);
PROCESS(clk)
VARIABLE count : INTEGER RANGE 0 TO 25_000_000;
BEGIN
IF(clk'EVENT AND clk = '1') THEN
IF(count < 25_000_000) THEN
count := count + 1;
ELSE
count := 0;
led <= NOT led;
END IF;
END IF;
END PROCESS;
END behavior;
For more reading please look at Lattice Diamond and MachXO2 Breakout Board Tutorial

Related

why do i need wait after assert in VHDL?

I've started learning VHDL, and on EdaPlayground there's always a wait; after assert(cond); in the testing file.
Could you please explain why do i need a wait; in the end? From my point of view, it should terminate right after execution, but it doesn't (and instead of terminating it lands into an infinite loop).
Here is the architecture i want to test :
use IEEE.std_logic_1164.all;
entity minority is
port(
a: in std_logic;
b: in std_logic;
c: in std_logic;
y: out std_logic
);
end minority;
architecture impl of minority is
begin
y <= '1' when (a and b and c) else '0';
end impl;
Here is the code for testing :
use IEEE.std_logic_1164.all;
entity testbench is
-- empty
end testbench;
architecture tb of testbench is
-- DUT component
component minority is
port(
a: in std_logic;
b: in std_logic;
c: in std_logic;
y: out std_logic
);
end component;
signal a1, b1, c1, y1: std_logic;
begin
-- Connect DUT
DUT: minority port map(a1, b1, c1, y1);
process
begin
a1 <= '0';
b1 <= '1';
c1 <= '0';
y1 <= '0';
wait for 1 ns;
assert(y1='0') report "Y is ok." severity error;
wait; -- <-- without this line, the test starts to execute infinitely :(
end process;
end tb;
Thank you for your answers!
VHDL is a hardware description language. The VHDL process is a key part of it. Hardware doesn't just stop. Therefore, VHDL processes don't just stop, either; they keep on going, just like hardware does.
If you want to use a process for something other than hardware design (ie you are not going to synthesise it) and you want it to only run once, then you are going to have make it stop. You do that by adding a wait statement, because in VHDL, a wait on its own means wait forever.

How do I assign data to an internal input port

I have an FPGA trying to read/write values to SDRAM on the same chip. What the sdram sees as IN, the top level sees as OUT and otherwise. SDRAM "paths" are instantiated and are brought to the top level. These paths have no direction. However, I know that the top level reads and writes to the sdram. I tried a variation of the code shown and it compiled. The code below is an example to pass two values to the SDRAM and read a third value. I have assigned a direction to paths. Is my logic correct in that it sends two values and received a third?
use IEEE.STD_LOGIC_UNSIGNED.ALL; -- see page 36 of Circuit Design with VHDL
port(
-- ---------------------------------------------------------------------
-- Global signals ------------------------------------------------------
CLK : in std_logic;
RESET : in std_logic;
A : out std_logic_vector(15 downto 0);
B : out std_logic_vector(15 downto 0);
C : in std_logic_vector(15 downto 0);
end entity sigma_k_top;
architecture rtl of function_top is
signal cntr : std_logic_vector(31 downto 0);
signal sig_A : std_logic_vector(15 downto 0);
signal sig_B : std_logic_vector(15 downto 0);
signal sig_C : std_logic_vector(15 downto 0);
begin
sdram_inst : entity work.sdram
port map (
CLK => sdram_CLK_in, --CLK shared by all
A => sdram_A_in, -- Write to sdram
B => sdram_B_in,-- Write to sdram
C => sdram_C_out, --Read from sdram
);
transfer: process(CLK)
begin
IF rising_edge(CLK) then
cntr <= cntr + 1;
if cntr = 1000 then --
sig_A <= "1000000000000000";
sig_B <= "1000000000000000";
end if;
if cntr = 1001 then
if C(0) = '1' then
sig_A <= sig_A - 1; -- Writing
sig_B <= sig_B + 1; -- Writing
xfer <= C ; -- Reading
end if;
end if;
if cntr > 2000 then
cntr <= (others => '0');
end if;
END IF;
end process;
-- -------------------------------------------------------------------------
-- Top-level ports ---------------------------------------------------------
TEST_LED(7 downto 0) <= xfer(7 downto 0); -- Making some sdram output visible
A <= sig_A; -- Sending value to sdram
B <= sig_B; -- Sending value to sdram
end architecture rtl;
What inputs and outputs exist to/from the RAM could vary based on how you intend to use it. If the RAM really exists on the FPGA chip itself, an example might be that you want to use a simple single port RAM on say a Xilinx Block RAM library component.
As it appears from the code that the sdram is instanced under the FPGA's top level (the RAM is contained within the fpga chip), it seems that the what are the RAM's inputs/outputs should also be the top level's inputs/outputs. It would be reversed if the sdram were outside the FPGA (and thus outside the FPGA's top level)
In general, RAMs tend to be sequential elements that require at the least:
-A clock (typically a 1-bit wide signal)
-An address (tends to be log2(n) bits wide, where n is the size of the RAM array. So if the array has 64 elements, you'd need at least 6 bits to address everything. The same address signal could be used for both reads and writes, or maybe you would have 2 separate address signals.)
-A write enable (in the simplest from could be a 1-bit signal. The most typical use would be to assert this signal for 1 clock cycle to update data at the current address of the address signal)
-data (width would vary and tends to be flexible/configurable on an FPGA. If you want to store 16-bits of data in each RAM entry that should be perfectly valid. This could be a single signal or 2 separate ones for read and write data).
As long as the signal vectors going to/from the RAM have at least these basic functions, it seems like you should be able to use it at least as a simple RAM. Note by the way that in your code the sdram_* signals are neither declared nor connected to anything other than the sdram instance itself.

Ring Oscillator in Verilog using generate

I'm looking to create a ring oscillator in Verilog, using inverters and generate.
Here's what I've tried so far:
module ringOsc(outclk);
parameter SIZE = 8; // This needs to be an even number
output outclk;
wire [SIZE : 0] w;
genvar i;
generate
for (i=0; i<SIZE; i=i+1) begin : notGates
not notGate(w[i+1], w[i]);
end
not notGateFirst(w[0], w[SIZE]);
endgenerate
assign outclk = w[0];
endmodule
This will be loaded onto an FPGA and the frequency of oscillation will be measured (of course with more than 9 inverters). Is this correct or am I missing something? Any help would be appreciated.
For a ring oscillator you need to have a delay. The not gates you are using have no such delay in simulation as they are ideal models.
Simplest is to add a delay to the gates:
not #(5,5) notGate(w[i+1], w[i]);
not #(5,5) notGateFirst(w[0], w[i]);
Also it is good practice to have en enable: one of the gates is a NAND gate.
You also need to tell the tool not to optimise your ring oscillator away. For that you have to look at the synthesis tool of your FPGA, especially the constraints settings to prevent logic optimization. Defining the intermediate nets as 'keep' might work.

Simple oscillator in VHDL

I've just started with VHDL, and I have a problem understanding how exactly process operates. Here is an example of a simple oscillator:
timer_1Hz: process(clk) is
variable timer : integer := 0;
constant period : integer := 50E6;
begin
--if rising_edge(clk) then
timer := (timer+1) rem period;
if (timer=0) then
led <= not led;
end if;
--end if;
end process timer_1Hz;
clk is an input (clock) signal with 50 MHz frequency, and 50% duty cycle.
Now, as I understand it, the process timer_1Hz will be triggered on any change in the clk signal, whether that be a transition from 0 to 1, or from 1 to 0.
I expected from the above example to flash LEDs with a frequency of 0.5 Hz, since the rising_edge test was commented out. In other words, I expected that the body will be triggered two times in a single clock period, on a rising and a falling edge. However, that doesn't seem to work, i.e., LEDs are never turned on.
If I include the rising_edge test, LEDs blink with a 1 Hz frequency, just as I expected.
Can someone please explain what am I missing in the unexpected case.
The code will not work without the rising edge part you removed. It might work in simulation, but not in a real fpga board. Why? Because sensitivity list is (mostly) important for simulation and not(so much) for synthesis.
For synthesis purpose, you have to always think about the hardware you would be implementing. In a practical sense, a process is NOT "run" when certain events occur.
If you really want 0.5 Hz output, just use 25E6 instead of 50E6 with the original code..

Combinational Logic Timing

I am currently trying to implement a data path, which calculates the following, in one clock cycle.
Takes input A and B and add them.
Shift the result of addition, one bit to right. (Dividing by 2)
Subtract the shifted result from another input C.
The behavioral architecture of the entity is simply shown below.
signal sum_out : std_logic_vector (7 downto 0);
signal shift_out : std_logic_vector (7 downto 0);
process (clock, data_in_a, data_in_b, data_in_c)
begin
if clock'event and clock = '1' then
sum_out <= std_logic_vector(unsigned(data_in_a) + unsigned(data_in_b));
shift_out <= '0' & sum_out(7 downto 1);
data_out <= std_logic_vector(unsigned(data_in_c) - unsigned(shift_out));
end if;
end process;
When I simulate the above code, I do get the result I expect to get. However, I get the result, after 3 clock cycles, instead 1 as I wish. The simulation wave form is shown below.
I am not yet familiar with implementing designs with timing concerns. I was wondering, if there are ways to achieve above calculations, in one clock cycle. If there are, how can I implement them?
Do do this with signals simply register only the last element in the chain (data_out). This analyzes, I didn't write a test bench to verify simulation.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity signal_single_clock is
port (
signal clock: in std_logic;
signal data_in_a: in std_logic_vector(7 downto 0);
signal data_in_b: in std_logic_vector(7 downto 0);
signal data_in_c: in std_logic_vector(7 downto 0);
signal data_out: out std_logic_vector(7 downto 0)
);
end entity;
architecture behave of signal_single_clock is
signal sum_out : std_logic_vector (7 downto 0);
signal shift_out : std_logic_vector (7 downto 0);
begin
sum_out <= std_logic_vector(unsigned(data_in_a) + unsigned(data_in_b));
shift_out <= '0' & sum_out(7 downto 1);
single_reg:
process (clock)
begin
if clock'event and clock = '1' then
data_out <= std_logic_vector(unsigned(data_in_c) - unsigned(shift_out));
end if;
end process;
end architecture;
When you assign a new value to a signal inside a process, this new value will be available only after the process finishes execution. Therefore, anytime you read the signal's value you will be using the original value from when the process started executing.
On the other hand, assignments to varibles take place immediately, and the new value can be used in the subsequent statements if you wish.
So, to solve you problem, simply implement sum_out, shift_out, and data_out using variables, instead of signals. Then simply copy the value of data_out to an output port of your entity.
Without using variables:
sum <= in_a + in_b;
process (clock)
begin
if rising_edge(clock) then
data_out <= in_c - ('0' & sum(7 downto 1));
end if;
end process;
All declarations except clock are unsigned(7 downto 0); why make it more complicated than that?
The original, pipelined to 3 cycles, will probably work at higher clock rates.
EDIT following comment:
I wanted to demonstrate that VHDL doesn't really have to be that verbose.
However there seem to be a lot of people "teaching" VHDL who are focussing on trivial elements and missing the big picture entirely, so I'll say a little bit about that.
VHDL is a strongly typed language, to prevent mistakes that creep in when types are mistaken for each other and (e.g.) you add two large numbers and get a negative result.
It does NOT follow from that, that you need type conversions all over the place.
Indeed, if you need a lot of type conversions, it's a sign that your design is probably wrong, and it's time to rethink that instead of ploughing ahead down the wrong path.
Code - in ANY language - should be as clean and simple as possible.
Otherwise it's hard to read, and there are probably bugs in it.
The big difference between a C-like language and VHDL is this:
In C, using the correct data types you can write sum = in_a + in_b;
and it will work. Using the wrong data types you can also write sum = in_a + in_b;
and it will compile just fine; what it actually does is another matter! The bugs are hidden : it is up to you to determine the correct types, and if you get it wrong there is very little you can do except keep on testing.
in VHDL, using the right types you can write sum <= in_a + in_b;
and using the wrong types, the compiler forces you to write something like sum <= std_logic_vector(unsigned(in_a) + unsigned(in_b)); which is damn ugly, but will (probably: see note 1) still work correctly.
So to answer the question : how do I decide to use unsigned or std_logic_vector?
I see that I need three inputs and an output. I could just make them std_logic_vectorbut I stop and ask: what do they represent?
Numbers.
Can they be negative? Not according to my reading of the specification (your question).
So, unsigned numbers... (Note 1)
Do I need non-arithmetic operations on them? Yes there's a shift.(Note 2)
So, numeric_std.unsigned which is related to std_logic_vector instead of natural which is just an integer.
Now you can't avoid type conversions altogether. Coding standards may impose restrictions such as "all top level ports must be std_logic_vector" and you must implement the external entity specification you are asked to; intermediate signals for type conversions are sometimes cleaner than the alternatives, e.g. in_a <= unsigned(data_in_a);
Or if you are getting instructions, characters and the numbers above from the same memory, for example, you might decide the memory contents must be std_logic_vector because it doesn't just contain numbers. But pick the correct place to convert type and you will find maybe 90% of the type conversions disappear. Take that as a design guideline.
(Note 1 : but what happens if C < (A+B)/2 ? Should data_out be signed? Even thinking along these lines has surfaced a likely bug that std_logic_vector left hidden...
The right answer depends on unknowns including the purpose of data_out : if it is really supposed to be unsigned, e.g. a memory address, you may want to flag an error instead of making it signed)
(Note 2 : there isn't a synthesis tool left alive that won't translate
signal a : natural; ... x <= a/2 into a shift right, so natural would also work, unless there were other reasons to choose unsigned. A lot of people seem to still be taught that integers aren't synthesisable, and that's just wrong.)