How do you run a SCL file in MPLAB without a "Run SCL" button - microcontroller

I have an assembly code for PIC18F458 that gets data from channel 0 (RA0) of ADC and displays the result on PORTC and PORTD.
Therefore, I am trying to stimulate the RA0 pin on a PIC18F458 using a SCL file in the MPLAB X V5.05 Stimulus window.
Although, the file is successfully attached (see Image 1); when I run the simulation, there is no way of confirming if the SCL is actually being ran, aside from the ADRESL and ADRESH regsiters not containing any values (see image 2).
Simulator Window without Run SCL button
No data in ADRESH and ADRESL registers
Additionally, I do not have a "Run SCL" button; unlike the other examples that I have seen online. (Please see image 1 above)
UPDATE:
Slightly modifying the examples provided by #Kozmotronik, I have been able to confirm that the SCL file is running and the injection of data onto the AIO pin. Therefore, this particular question can now be considered closed!!

After some research in SCL Code Repo and SCL User's guide that is provided within MPLAB IDE help, and also after some test, I couldn't manage to get values from a file even with a direct SCL code. The SCL code I used first is the following:
configuration for "pic18f458" is
end configuration;
testbench for "pic18f458" is
begin
// Register Injection
process is
file fileVar : text;
variable status : file_open_status;
variable val : integer;
begin
report("Analog injection started...");
file_open(status, fileVar, "<data_file_path>", read_mode);
if status == open_ok then
report("Reading the values file...");
while endfile(fileVar) == false loop
read(fileVar, val);
wait until ADCON0.GO_nDONE == '1';
report("Conversion started");
wait until ADCON0.GO_nDONE == '0';
report("Conversion ended");
if ADCON1.ADFM == '0' then -- left justified
ADRESH <= val / 4;
ADRESL <= val * 64;
else -- right justified
ADRESH <= val / 256;
ADRESL <= val;
end if;
end loop;
file_close(fileVar);
wait;
end if;
end process;
end testbench;
I did saw the report strings in the simulator output but the ADRES registers are always injected with 0xFFFF value. I tried modified versions with no success.
However, when I decided to modify the SCL code and give it a try with an in-code variable it did worked. The values of the in-code variable were injected correctly. From this case I figured out that the file read operation fails in somewhere and can't get the value from the file correctly. The latter working SCL code is the following:
configuration for "pic18f458" is
end configuration;
testbench for "pic18f458" is
begin
// Register Injection
process is
file fileVar : text;
variable status : file_open_status;
variable val : integer;
begin
report("Analog injection started...");
val := 7;
while val < 1024 loop
wait until ADCON0.GO_nDONE == '1';
report("Conversion started");
wait until ADCON0.GO_nDONE == '0';
report("Conversion ended");
if ADCON1.ADFM == '0' then -- left justified
ADRESH <= val / 4;
ADRESL <= val * 64;
else -- right justified
ADRESH <= val / 256;
ADRESL <= val;
end if;
val := val * 8;
end loop;
report("Analog injection ended...");
wait;
end process;
end testbench;
The above SCL code will inject the actual value of the val variable everytime an ADC conversion ends (GO_nDONE bit first goes high and when the conversion is completed goes low). The value injection is made depending on the ADFM bit. if it is set to 0 the value will be left justified, otherwise will be right justified.
So I have posted an issue in the microchip forums regarding this matter. Let's see how it will be resolved.
Well if the values need not to be very specific you can make use of the second SCL code. However, in order to enable register injection in MPLABX IDE you need to configure the simulator first. To do this
Open the project properties window by clicking File -> Project Properties in the menu.
Then from categories section select Simulator.
Select Periph: ADC1 from the Option categories in the right pane.
Finally make sure that Use MPLAB 8 Style Stimulus/SCL for ADCxBUF0 is checked as in the following image.
Once you've configured it open the stimulus window, first start the simulation once so that it shows its content and then click on Attach SCL file icon to attach your SCL file and finally restart the simulation with the newly attached SCL.
UPDATE
I just simplified this example from the SCL repository and boom it works!
What I change in the code is; I was reading from the text file directly into the SCL variable which gives me no success, with the help of the SCL repo example, I created a line variable called dline, I read from a file into the dline using readline() builtin function, then I read from dline into the val variable using the read() function which resulted with success. The ADRES registers did injected with the correct values by each reading. Here is the updated code:
end configuration;
testbench for "pic18f458" is
begin
// Register Injection
process is
file fileVar : text;
variable status : file_open_status;
variable dline : line;
variable val : integer;
begin
report("Analog injection started...");
file_open(status, fileVar, "<data_file_path>", read_mode);
if status == open_ok then
report("Reading the values file...");
while endfile(fileVar) == false loop
wait until ADCON0.GO_nDONE == '1';
readline(fileVar, dline);
read(dline, val);
report("Conversion started");
wait until ADCON0.GO_nDONE == '0';
report("Conversion ended");
if ADCON1.ADFM == '0' then -- left justified
ADRESH <= val / 4;
ADRESL <= val * 64;
else -- right justified
ADRESH <= val / 256;
ADRESL <= val;
end if;
end loop;
file_close(fileVar);
wait;
end if;
end process;
end testbench;
Here is the data file. Note that the values are separated with new lines:
1
3
7
15
31
63
127
255
511
755
927
1023
1015
988
775
550
285
137
79
47
24
12
5
1

Related

Is an asynchronous counter made in Verilog synthesizable?

the question in it itself is simple. Is it possible to synthesize an Asynchronous counter in Verilog?
More explanation:
So for example, if I have something like the following code, is it possible to synthesize it?
always #(posedge clk) begin
//rst
if(!rst)begin
enable <=0;
end else begin
enable <= 1;
end
end
//action loop
always #(state) begin
case (state)
0:begin
cnt <= cnt
end
1: begin
cnt <= cnt + 1;
next_state <= 1;
end
default: begin
cnt <= cnt;
end
endcase
end
//state loop
always #(next_state, control, enable) begin
if(enable)begin
if(!control) begin
state <= next_state;
end else begin
state <= 0;
end
end
end
Here the general idea is that the counter will go asynchronously while the input control flag is 0, if it is 1 then the counter will be stopped until the input control flag becomes 0 again.
Note: I know I could try and synthesize the code and see what happens. But before that, I would like to know more and see if people have tried it.
Thanks for reading!!
Your action loop can't be properly synthesized.
What it is doing when state == 1?
Your state loop is synthesizable except but you will produce a latch (to store the value when enable == 0). This block is something that could be done using combinational logic '=' instead of non-blocking assignment '<='.

VHDL asynch ripple counter glitch

Here is a design for 4-bit asynchronous ripple counter (using T flip flop however I didn't define a component for Tff and just coded the behavior of circuit regarding T signals).
Following are the questions:
1.) inout ports, I first defined Q as inout (since it's obviously my output and the bits are also used as clk inputs to their following flip flops). Still, when I wanted to simulate my code, the Q output was UUUU which makes sense cause I had to initialize it with the number I wanted my count to begin with. Though I didn't know how to set an inout initial value (I tried Process ... Q <= "0000"; wait; end process but it didn't work)!
2.) In order to solve the above-mentioned problem I changed my inout port to out (Q_out) and defined Q as a signal, this worked BUT...my counter only changed the Q(0) bit and not the others...thus it counts like: 0,1,0,1,0,1,...
3.) I want to debug this code. I tried another style, instead of a 4-bit output I defined 4 1-bit output signals (Q_out1 to Q_out2) in addition to 4 internal signals Q0 to Q1 and this perfectly works
I just want to know why the first style (Q as a 4_bit vector) didn't work out.
thanks in advance for your help.
Here is my code and its test bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity four_bit_Asynch_Counter is
Port ( T0,T1,T2,T3 : in STD_LOGIC;
clk : in STD_LOGIC;
Q_out: out STD_LOGIC_VECTOR (3 downto 0));
end four_bit_Asynch_Counter;
architecture Behavioral of four_bit_Asynch_Counter is
signal Q : STD_LOGIC_VECTOR (3 downto 0) := "0000";
begin
Process (clk,Q(0),Q(1),Q(2))
begin
if (falling_edge(clk)) then
if (T0 = '1') then
Q(0) <= not Q(0);
else
Q(0) <= Q(0);
end if;
end if;
if (falling_edge(Q(0))) then
if (T1 = '1') then
Q(1) <= not Q(1);
else
Q(1) <= Q(1);
end if;
end if;
if (falling_edge(Q(1))) then
if (T2 = '1') then
Q(2) <= not Q(2);
else
Q(2) <= Q(2);
end if;
end if;
if (falling_edge(Q(2))) then
if (T3 = '1') then
Q(3) <= not Q(3);
else
Q(3) <= Q(3);
end if;
end if;
Q_out <= Q;
end Process;
end Behavioral;
--------------- Test Bench------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb_counter IS
END tb_counter;
ARCHITECTURE behavior OF tb_counter IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT four_bit_Asynch_Counter
PORT(
T0 : IN std_logic;
T1 : IN std_logic;
T2 : IN std_logic;
T3 : IN std_logic;
clk : IN std_logic;
Q_out : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal T0 : std_logic := '1';
signal T1 : std_logic := '1';
signal T2 : std_logic := '1';
signal T3 : std_logic := '1';
signal clk : std_logic := '0';
--Outputs
signal Q_out : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: four_bit_Asynch_Counter PORT MAP (
T0 => T0,
T1 => T1,
T2 => T2,
T3 => T3,
clk => clk,
Q_out => Q_out
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;
The TL;DR answer is that q(3) doesn't show up in your process sensitivity list.
architecture behavioral of four_bit_asynch_counter is
signal q: std_logic_vector (3 downto 0) := "0000";
begin
process (clk, q(0), q(1), q(2))
begin
if falling_edge(clk) then
if t0 = '1' then
q(0) <= not q(0);
-- else
-- q(0) <= q(0);
end if;
end if;
if falling_edge(q(0)) then
if t1 = '1' then
q(1) <= not q(1);
-- else
-- q(1) <= q(1);
end if;
end if;
if falling_edge(q(1)) then
if t2 = '1' then
q(2) <= not q(2);
-- else
-- q(2) <= q(2);
end if;
end if;
if falling_edge(q(2)) then
if t3 = '1' then
q(3) <= not q(3);
-- else
-- q(3) <= q(3);
end if;
end if;
q_out <= q;
end process;
end architecture behavioral;
For your process sensitivity list you've discovered a feature in how the sensitivity list is constructed from the expression consisting of primaries - clk, q(0), q(1), q(2).
From IEEE Std 1076 -1993, 8.1 Wait statement:
...
The sensitivity set is initially empty. For each primary in the condition of the condition clause, if the primary is
-- A simple name that denotes a signal, add the longest static prefix of the name to the sensitivity set
-- A selected name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set
-- An expanded name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set
-- An indexed name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set and apply this rule to all expressions in the indexed name
...
...
This rule is also used to construct the sensitivity sets of the wait statements in the equivalent process statements for concurrent procedure call statements( 9.3 ), concurrent assertion statements ( 9.4 ), and concurrent signal assignment statements ( 9.5 ).
If a signal name that denotes a signal of a composite type appears in a sensitivity list, the effect is as if the name of each scalar subelement of that signal appears in the list.
...
I only included elements of the rule that are of interest here, the first covers the clock the last element shown covers the std_logic_vector elements specified by selected names.
It helps to understand what is meant by the longest static prefix. This explained in -1993 6.1 Names.
The primaries (indexed names) are static names (q(0), q(1), q(2)), every expression that's part of each indexed name is static.
This means the longest static prefix is the indexed name comprising each primary.
And this leaves q(3) dangling in the breeze for the process signal assignment statement:
q_out <= q;
Without sensitivity to q(3) the value of q_out is not updated until the next event in the sensitivity list, which happens to be on clk:
There are two ways to cure this, you could move the q_out assignment outside the process statement, where it becomes a concurrent signal assignment (with an elaborated equivalent process with a sensitivity list set to q), or you can change the sensitivity list in the present process:
process (clk, q)
So that q_out is updated for an event on q(3) (noting the last quoted paragraph in 8.1 above).
This behavior hold true for later revisions of the standard as well.
With the process sensitivity list is fixed:
Your counter behaves properly.
Also note I commented out the redundant else assignments to the q(0), q(1), q(2) and q(3) a signal will hold it's value until assigned and these are sequential (clocked) statements. Also eliminated the redundant parentheses pairs.
When implementing counters in realisable hardware (either ASIC or FPGA) you should never use a ripple counter. By using the flip-flop output as a clock to the next you will have sub-optimal timing, the tools will not be able to accurately validate the setup and hold times and you are not able to take advantage of dedicated clock routing. In general asynchronous design is a bad idea for real implementations.
A true synchronous design will be much better for synthesis and is much easier to infer in the VHDL code.
Examples of Counter implementations
See the above link for both verilog and vhdl examples of counter implementation.

Asynchronous reset mysteriously setting up output reg

I have this code below:
module timer(
input clk,
input reset,
output reg signal // <--- PROBLEMATIC SIGNAL
);
always#(posedge clk or posedge reset)
begin
if(reset)
signal <= 1;
else
signal <= 0;
end
endmodule
and this testbench, which was executed on modelsim:
`timescale 1ns / 1ps
`define PERIOD 20
module timer_tb;
logic clk;
logic reset;
logic signal;
timer inst(
.clk(clk),
.reset(reset),
.signal(signal)
);
initial
begin
clk = 0;
forever clk = #(`PERIOD/2) ~clk;
end
initial
begin
reset = 0; //<--- RESET STARTS CLEANED.
#(`PERIOD)
reset = 1;
#(`PERIOD)
reset = 0;
#(`PERIOD*3)
reset = 1;
#(`PERIOD)
reset = 0;
#(`PERIOD*3)
$display("End of the simulation");
$stop;
end
endmodule
Output reg signal starts HIGH but in the code, this reg depends of reset, and the reset starts DOWN. I don't understand why signal register is HIGH in the beginning of the simulation as the reset starts surely DOWN.
I need the signal starting DOWN and only be set up IF reset go to 1 (condition posedge reset just like my code).
Please take a look on this print of the waveform for clear understanding of my problem.
Your waveform has clock-to-q delay, but your RTL model doesn't have any delay. This implies you are not running RTL simulation. Rather your are running a synthesized gate level simulation or getting output from an FPGA.
Something to consider is that in the test bench, clk and reset start as X not 0. The become 0 at time zero. Verilog allows indeterminate order for parallel process, it is optional to execute an always block at time zero regardless of its sensitivity list, and an X in for a comparison evaluates as true. Depending how the vendor implemented the simulator, it is possible the always block got executed first. reset being X evaluates as true and assigns signal to 1. Then clk and reset are assigned to 0. All of this happens at time 0 and cannot be seen in waveform.
This allowed unpredictability is an unintentional slice of reality. When you first power up a circuit what you initially get may be unpredictable (this is from process variation, physical routing, glitches while the power supply is being ramped, etc. ). You use a reset to get the design into a known state.
If you want to prevent the clk and reset from ever begin X, then change the data-type in the test-bench from logic to bit (note:bit and logic are SystemVerilog). Another option that should work (not 100% guaranteed) is to initialize clk and reset in the same line as it's declaration.
logic clk = 1'b0;
logic reset = 1'b0;
This should work assuming you are running simulation. If you are running on FPGA you cannot guaranty this time zero behavior through changes in your test bench.
The cleanest solution is to start with reset enabled. You should not care what the values are before reset at time zero.
signal has not initial value, so its value at time 0 is undefined. Some simulators initialize it to 0, others to 1, others to X.
Use an initial block to have signal initialized to 0.
module timer(
input clk,
input reset,
output wire signal
);
reg rsignal;
assign signal = rsignal;
initial begin
rsignal = 1'b0;
end
always#(posedge clk or posedge reset)
begin
if(reset)
rsignal <= 1;
else
rsignal <= 0;
end
endmodule
The default value of reg is 'x' or undefined and default value of wire is 'Hi-Z' , so in this case your output (signal) is reg type so simulator took default value accordingly, to get a default value of '0' SystemVerilog(IEEE1800-2012) comes with bit data type, you can try using bit in the output as shown below
module timer(
input clk,
input reset,
output bit signal
);
always#(posedge clk or posedge reset)
begin
if(reset)
signal <= 1;
else
signal <= 0;
end
endmodule
EDIT: I am not sure of quartus but conversely you can try initializing the value to 0 or 1 at the output by this method, It should work in Verilog
module timer(
input clk,
input reset,
output reg signal=0
);
always#(posedge clk or posedge reset)
begin
if(reset)
signal <= 1;
else
signal <= 0;
end
endmodule

Multiple buttons

How to change this code to get it working with several (2, 3 or 4) buttons?
signal lastButtonState : std_logic := '0';
process(clk)
begin
if(rising_edge(clk)) then
if(buttonState = '1' and lastButtonState = '0') then --assuming active-high
--Rising edge - do some work...
end if;
lastButtonState <= buttonState;
end if;
end process;
I would like to get several buttons work and do some work on press 'state'. This part of code works for 1 button only.
Thanks
The std_logic_vector type can be used for multiple buttons. Code may look
like:
constant BUTTONS : positive := 4; -- Number of buttons
subtype buttons_t is std_logic_vector(1 to BUTTONS); -- Type for buttons
signal buttonsState : buttons_t; -- Input from buttons (remember to debounce)
signal lastButtonsState : buttons_t := (others => '0'); -- Last state
... -- End of declarations, and start of concurrent code (processes etc.)
process (clk)
variable buttonsRise_v : buttons_t; -- Support variable to make writing easier
begin
if rising_edge(clk) then
buttonsRise_v := buttonsState and (not lastButtonsState); -- Make '1' for each button going 0 to 1
if buttonsRise_v(1) = '1' then -- Detect button 1 going 0 to 1
-- Do some work...
end if;
-- More code reacting on buttons...
lastButtonsState <= buttonsState;
end if;
end process;

RS232 transmitter module in vhdl latches?

I'm trying to write RS232 transmitter module in vhdl for Spartan. According to simulation in Xilinx, it seems to be working fine, but when i try to deploy it on device, it simply doesn't work. I have found out that it might be problem with latches, but somehow I'm not able to pinpoint them. I'm using 50 Mhz clock and the bit rate of transmission is 115200 bs.
This is my vhdl code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_arith.all; -- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity nadajnikRS is
Port ( start : in STD_LOGIC;
reset : in STD_LOGIC;
clk : in STD_LOGIC;
DI : in STD_LOGIC_VECTOR(7 downto 0);
RS_TX : out STD_LOGIC;
busy : out STD_LOGIC);
end nadajnikRS;
architecture Behavioral of transRS is
signal register : STD_LOGIC_VECTOR(8 downto 0) := (others => '1' );
signal counter : INTEGER range 0 to 9 := 0;
signal baud_clk : STD_LOGIC := '0';
signal ready : STD_LOGIC := '0';
type states is (working, free);
signal state: states := free;
signal baud_counter : INTEGER range 0 to 220 := 215;
begin
baud_clock: process (clk)
begin
if rising_edge(clk) then
if (ready = '1') then
if (baud_counter < 218) then
if (baud_counter = 217) then
baud_clk <= '1';
end if;
baud_counter <= baud_counter+1;
else
baud_counter <= 0;
baud_clk <= '0';
end if;
else
baud_counter <= 0;
end if;
end if;
end process baud_clock;
shiftregister : process (baud_clk)
begin
if rising_edge(baud_clk) then
if (state = free) then
RS_TX <= '0';
register (7 downto 0) <= DI;
else
RS_TX <= register(0);
register <= '1' & register(8 downto 1);
end if;
end if;
end process shiftregister;
bitcounter : process (baud_clk)
begin
if rising_edge(baud_clk) then
counter <= counter + 1;
if (counter = 10) then
counter <= 1;
end if;
end if;
end process bitcounter;
shiftstate: process (reset, counter, start)
begin
if (reset = '1') then
ready <= '0';
end if;
if (start = '1') then
ready <= '1';
state <= free;
end if;
if (counter = 1 ) then
state <= working;
elsif (counter = 10) then
state <= free;
end if;
end process;
statemachine : process (state)
begin
case state is
when working => busy <= '1';
when free => busy <= '0' ;
end case;
end process statemachine;
end Behavioral;
During synthesis I get two latch warnings:
Xst:737 - Found 1-bit latch for signal <ready>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
Xst:737 - Found 1-bit latch for signal <state_0>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
I tried to eliminate them by adding additional if statements, but nothing seems to work.
I will be grateful for any help,
Ghaad
A process describing a register should have exactly one signal in the sensitivity list, clk (possibly a reset signal as well if you use asynchronous resets), since a register is only sensitive to a single event, namely a clock edge.
Thus your process sensitivity list baud_clock: process (clk,ready) and shiftregister : process (baud_clk, state) already indicate that you have a problem.
When describing a register, always make sure that your if(rising_edge(clk)) surrounds ALL of the described logic. A simple registered process should look like this:
process(clk) begin
-- NO LOGIC HERE
if(rising_edge(clk)) then
if(reset='1') then
-- Synchronous reset logic here.
else
-- All other logic here.
end if;
end if;
-- NO LOGIC HERE
end process;
Look at your 'shiftstate' process, which is responsible for driving 'ready'. How does it drive 'ready' when 'reset' is not 1, and 'start' is not 1? You haven't told it, so it keeps 'ready' unchanged in those cases. That's what 'latch' means: the process needs to remember what 'ready' was before, and keep it the same; your code therefore infers a memory. Make sure that 'ready' is driven in all branches; you can do this easily with a default assignment at the top.
Having said that, your code has multiple other issues. Did someone suggest in another thread that you shouldn't have your rising edge detection inside an if statement? Or was that someone else? Go back and read it again.
Try to fill all the posibilities of if statements so that for every run the program will know which value correspond to a variable. If statement has almost always go with else or elsif options to not produce latches..
A latch can occur when a process is allowed to go from start to finish without the driven outputs being assigned a value. That is if you have any conditional statements in your process and your outputs are driven inside these conditional statements then there a high chance that the outputs may never be driven. To avoid this it is good practice to place a concurrent statement at the beginning of your process to ensure your outputs are being set at least once. This will tell your synthesiser not to create a latch.

Resources