How to check the state machine case in testbench - vhdl

I am writing a code for spi slave and wishbone bus. The issue is that the testbench file shows all the signals correctly (the signals and ports that are used in testbench) but when I am trying to check the state machine in the main code it shows nothing red line. I tried to define an output port and assign the state to it, it did not work because I don't know how to make an output port as a string because the state is like this
TYPE wb_state_t IS
(
WB_IDLE,
WB_WRITE,
WB_READ,
WB_FINISH
);
SIGNAL wb_state : wb_state_t;
I want to assign wb_state to an output port so I can check the state in the testbench.
How can I do that?

As you read in the comments, I only needed to make a simple package and put the state machine cases in it and call it in both the top level and the testbench files.
Library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package wb_state_machine is
TYPE wb_state_t IS
(
WB_IDLE,
WB_WRITE,
WB_READ,
WB_FINISH
);
end package;

lot of simulator are able to display internal signal. for instance on vivado or Questa you can click on the design name when you are on the waves page. Then you take your signal and slide it on waves and rerun simulation

Related

DUT unrecognized in modelsim simulation

Unfortunately I can't properly debug a code in Modelsim. In fact, during the simulation the DUT is not displayed in the SIM panel (I am attaching a screenshot). So I can just see the waveforms generated by the testbench, but I cannot view the internal signals. It seems that for some reason the TESTER and the DUT are not connected.
You can add all the signals recursively with the following command:
add wave -recursive /*
Now, if you're not seeing the DUT, you may want to check the waring when the simulation is loading.
Do you see unbound warnings?
Did you compile your DUT file?
Do you find it in the library ?
Sébastien.

Altera Quartus II "Error (12061): Can't synthesize current design -- Top partition does not contain any logic"

I recently started working with FPGAs and have been trying to get a basic VHDL program up and running. My code is intended to take the inputs from 10 switches and map them to 10 LED outputs on my dev board, but when I attempt to run analysis/synthesis I get the error in the title. Analyzing the file individually by running "Analyze Current File" yields no errors. A similar post was made here, but the solution there does not help me. I have only one file in my project and I am certain that it has been specified as the top-level entity.
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity sw_to_led is port(
SW: in bit_vector(9 downto 0);
LED: out bit_vector(9 downto 0));
end sw_to_led;
architecture behavior of sw_to_led is
begin
LED <= SW after 5ns;
end behavior;
I thought that the top-level file had to have the same name as the specified "top-level design entity", instead of the entity itself. I learned to read and changed the name of the actual entity to match what was specified and it fixed the issue.
1) Is the name of the vhdl file the same as the entity name sw_to_led.vhd ?
2) Are there already partitions in your design? If yes, you can try making a new Quartus-Project with the help of the "New Project Wizard" and add only the file sw_to_led.vhd.
By the way, after 5ns is not synthesizable. It should only be used in the simulation. But for Quartus it's not an error.

iCEstick + yosys - using the Global Set/Reset (GSR)

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.

How can I write sequential component with case

Below code is not compiling. How can I modify it to make it works? Thank you.
case S is
when '0' =>
U1: hi port map (x,y,z);
when others =>
U2: hey port map (x,y,z);
end case;
Without the rest of the code there will be some guessing, but you have probably used case outside a process, thus the "illegal concurrent statement" message, since case is a statement that can only be used in a process. However, component instantiation with port map (x,y,z) is a concurrent statement, thus can only be used outside a process.
VHDL is not a programming language, but a Hardware Description Language (the HDL part of VHDL), thus when writing VHDL code, think of it like describing a electrical circuit, and in this the parts are fixed, but the signal values can vary over time.
So, instantiate the components outside a process with port map (x,y,z) and control the signal values from processes, other components, ports, etc.
As you are instantiating components, you are not within a process, hence you cannot use sequential programming constructs.
You can however use if ... generate which selectively generates hardware, on the value of S as long as S is a generic or constant. (If you could input a signal to if ... generate, that would require hardware to appear or disappear when the signal value changed ... not gonna happen!)
Note that if ... generate has no "elsif" or "else" options, so you have to express your example in a slightly more awkward fashion:
gen_S_0 : if S = '0' generate
U1: hi port map (x,y,z);
end generate;
gen_S_others: if S /= '0' generate
U2: hey port map (x,y,z);
end generate;

Preserving the widths of ports

I am trying to re-use netlists in other designs without the success.
I have a component which is translated to the netlist:
entity c is
port (... sel : in std_logic_vector(31 downto 0); ... );
In the design I am using just sel(4 downto 0).
The synthesis tools notices this behaviour and gives a warning:
'WARNING:Xst:647 - Input sel<31:5> is never used ..
I am generating netlist with properties:
keep hierarchy = true
add I/O buffers = off
Whenever I want to instantiate this netlist as an black-box module in other circuit I got an error:
ERROR:NgdBuild:76 - cannot be merged into block because one or more pins on the block, including pin "sel<31>", were not found in the file.
How can I preserve the size of sel?
I should mention that the sel needs to be 32bits width since it's connected to the bus.
You could try driving the unused input ports to zero.
Can you use the component directly instead of as a pre-synthesised black-box?
You may get things to work by putting a KEEP attribute (see your synth tools manual) on the port. I've only ever tried this on signals, but it may work.
This sort of task is often described as "pushing on the rope" of the synthesiser, as it's such a pain to get it to not be as celever as it wants to be (and then in the next release of tools you need a different attribute :)

Resources