Instead of this task just toggling tb.stimulus.top.Ichip0.vbiash high and low ten times I would like to be able to call it passing in any signal tb.stimulus.top.Ichip0.vbiasl, tb.stimulus.top.Ichip0.vbiasx, or tb.stimulus.top.Ichip0.vbiasz and make them toggle as well. For example toggle_signal(tb.stimulus.top.Ichip0.vbiasl); Is it possible to do this. If so I would really appreciate an example of how I would accomplish this.
task toggle_signal;
begin
for (monpad_index=0; monpad_index < 10; monpad_index = monpad_index + 1)
begin
#1000;
force tb.stimulus.top.Ichip0.vbiash = 1'b1;
#1000;
force tb.stimulus.top.Ichip0.vbiash = 1'b1;
#1000;
end
end
You cannot pas the name of a single to a task. But you can create a macro to do this.
`define toggle_signal(sig) \
for (monpad_index=0; monpad_index < 10; monpad_index = monpad_index + 1) \
begin \
#1000 force tb.stimulus.top.Ichip0.sig = 1'b1; \
#1000 force tb.stimulus.top.Ichip0.sig = 1'b0; \
#1000; \
end
and then write
`toggle_signal(vbiash)
`toggle_signal(vbiasl)
If you are not afraid do dive into a little C programming, you could write your own PLI/VPI. I suggest checking out IEEE Std 1800-2012's sections on PLI/VPI (§ 36, 37, & 38). Your come may looks something like the following (Note, the code is a starting reference. I haven't tested it):
static int my_vpi_force_release_calltf(PLI_BYTE* user_data) {
vpiHandle sys, argv, signal;
p_vpi_value p_value;
int force_release;
force_release = (int) user_data;
sys = vpi_handle(vpiSysTfCall, 0);
argv = vpi_iterate(vipArgument, sys);
signal = vpi_handle_by_name(vpi_get_str(vpi_scan(argv), 0);
if (force_release != 0 ) {
vpi_get_value(vpi_scan(argv), p_value);
vpi_put_value(signal, p_value, 0, vpiForceFlag);
} else {
vpi_get_value(signal, p_value);
vpi_put_value(signal, p_value, 0, vpiReleaseFlag);
}
return 0;
}
void register_my_vpi_force_release()
{
s_vpi_systf_data data;
data.type = vpiSysTask;
data.calltf = my_vpi_force_release_calltf;
data.tfname = "$my_force";
data.user_data = (PLI_BYTE8 *) 1;
vpi_register_systf(&data);
data.tfname = "$my_release";
data.user_data = (PLI_BYTE8 *) 0;
vpi_register_systf(&data);
}
You can call your PLI/VPI tasks in verilog:
task toggle_signal( input [80*8-1:0] path_str );
integer index;
begin
for (index=0; index < 10; index = index + 1)
begin
#1000;
$my_force( path_str, 1'b1);
#1000;
$my_force( path_str, 1'b0 );
#1000;
end
$my_release( path_str );
end
endtask
...
initial begin
...
toggle_signal( "tb.stimulus.top.Ichip0.vbiash" );
...
end
If you don't want to write your own custom PLI/VPI, then I suggest enabling SystemVerilog and include UVM (the major simulators have UVM build in, or download it yourself). The UVM library has a build in method uvm_hdl_force/uvm_hdl_release.
Here you go. The following code passes a signal name as a parameter to a task then prints the signal name as a string. Tested in iverilog.
reg this_is_some_signal_name;
`define NAME(net) `"net`"
task print;
input reg [32*8] str;
begin
$display(">>> %0s", str);
end
endtask
initial begin
print(`NAME(this_is_some_signal_name));
$finish;
end
Outputs:
>>> this_is_some_signal_name
Related
I am new one in Verilog and I need to write a simple test bench, but I get an error and I cannot understand why it is
Here is my code
`timescale 1 ns / 1 ns
module test_bench_lb2;
reg [12:0] in_lines_tb;
wire [4:0] out_lines_tb;
wire error_tb;
localparam PERIOD = 10;
initial
begin
genvar i;
for(i = 0; i <= 8000; i = i + 1)
begin
in_lines_tb = i;
#PERIOD;
end
#(PERIOD*20) $stop;
end
initial
begin
$monitor("time = %time in_lines = %b out_lines = %b error = %b",
$time, in_lines_tb, out_lines_tb, error_tb);
end
DESHIFRATOR inst1(.in_lines(in_lines_tb), .out_lines(out_lines_tb), .error(error_tb));
endmodule
This
genvar i;
should be this
integer i;
A genvar is a special kind of variable used in a construct called a generate loop. You code uses an ordinary for loop.
So I'm trying to instantiate a module within a module. The root module has output ports that drive the output pins and I want the inner module to drive those ports directly but I can't get it work anyway round.
/*
A root module for the 005_135-scanner_mainboard_revA_sch-pcb. Can be used as a test bench for testing peripheral devices but has been designed to be the master root module for the final code.
All IO is included and reset pins on peripheral devices driven active reset with data lines driven to an appropriate value (located in the ‘initial block’).
George Waller. 09/08/15.
*/
module root_module( ft_reset, ft_usb_prsnt, ft_bus_pwrsav, ft_bus_oe, ft_bus_clkout, ft_bus_siwu, ft_bus_wr, ft_bus_rd, ft_bus_rxf, ft_bus_txe, ft_bus_d,
mtr_fault, mtr_config, mtr_m1, mtr_m0, mtr_rst, mtr_out_en, mtr_step, mtr_dir,
ccd_driver_oe, ccd_p1, ccd_p2, ccd_cp, ccd_rs, ccd_sh,
dac1_sdin, dac1_sclk, dac1_sync, dac2_sdin, dac2_sclk, dac2_sync,
adc_pwrdn, adc_encode, adc_d,
fpga_reset,
clk,
gpio,
led_ctrl,
leds);
//Input declarations
input wire ft_usb_prsnt, ft_bus_clkout, ft_bus_rxf, ft_bus_txe,
mtr_fault,
fpga_reset,
clk;
input wire [7:0] adc_d;
//Output declarations
output reg ft_reset, ft_bus_pwrsav, ft_bus_oe, ft_bus_siwu, ft_bus_wr, ft_bus_rd,
mtr_config, mtr_m1, mtr_m0, mtr_rst, mtr_out_en, mtr_step, mtr_dir,
ccd_driver_oe, ccd_p1, ccd_p2, ccd_cp, ccd_rs, ccd_sh,
adc_pwrdn, adc_encode,
led_ctrl;
output reg dac1_sdin, dac1_sclk, dac1_sync, dac2_sdin, dac2_sclk, dac2_sync;
output reg [7:0] leds;
//Input output declarations.
inout reg [7:0] ft_bus_d;
inout reg [16:0] gpio;
//Variables go here
integer count, count1, state, pixel_n, line_n, t_int;
integer data[8];
reg en;
//Initial values on start up.
initial
begin
//IO initial setup values.
ft_reset = 1; ft_bus_pwrsav = 1; ft_bus_oe = 1; ft_bus_siwu = 0; ft_bus_wr = 1; ft_bus_rd = 1; //NEED TO APPLY REAL VAULES!!!
mtr_config = 1; mtr_m1 = 1; mtr_m0 = 1; mtr_rst = 1; mtr_out_en = 1; mtr_step = 0; mtr_dir = 0;
ccd_driver_oe = 1; ccd_p1 = 0; ccd_p2 = 0; ccd_cp = 0; ccd_rs = 0; ccd_sh = 0;
dac1_sdin = 0; dac1_sclk = 0; dac1_sync = 0; dac2_sdin = 0; dac2_sclk = 0; dac2_sync = 0;
adc_pwrdn = 0; adc_encode = 0;
led_ctrl = 0;
leds = 0;
gpio = 0;
ft_bus_d = 0;
//Variables setup values.
count = 0;
count1 = 0;
state = 0;
pixel_n = 0;
line_n = 0;
t_int = 10000; //t_int = integration time. integration time (seconds) = t_int * 10x10^-9.
end //End initial
//Some other code goes here.
always #(posedge ft_bus_clkout)
begin
if(count == 50000000)
begin
en <= 1;
count = 0;
end
else
begin
en <= 0;
count = count + 1;
end
end //End always
AD5601_module AD5601(.en(en), .clk(clk), .data(127),.sdout(dac1_sdin),
.sclk(dac1_sclk), .sync(dac1_sync));
endmodule //End module.
And the inner module:
module AD5601_module(en, clk, data, sdout, sclk, sync);
input wire clk;
input wire en;
input wire [7:0] data;
output reg sdout, sclk, sync;
integer sclk_count;
integer data_state;
integer delay_counter;
integer pd[2];
initial
begin
sclk_count = 0;
data_state = 99;
delay_counter = 0;
pd[0] = 0;
pd[1] = 0;
sdout = 0;
sclk = 0;
sync = 1;
end
always # (posedge en)
begin
if(data_state == 99)data_state <= 0;
end
always # (posedge clk)
begin
if(sclk_count == 49)
begin
sclk_count = 0;
sclk = ~sclk;
end
else sclk_count = sclk_count + 1;
end
always # (posedge sclk)
begin
case(data_state)
0: begin
sync = 0;
sdout <= pd[1];
data_state <= 1;
end
1: begin
sdout <= pd[0];
data_state <= 2;
end
2: begin
sdout <= data[7];
data_state <= 3;
end
3: begin
sdout <= data[6];
data_state <= 4;
end
4: begin
sdout <= data[5];
data_state <= 5;
end
5: begin
sdout <= data[4];
data_state <= 6;
end
6: begin
sdout <= data[3];
data_state <= 7;
end
7: begin
sdout <= data[2];
data_state <= 8;
end
8: begin
sdout <= data[1];
data_state <= 9;
end
10:begin
sdout <= 0;
if(delay_counter == 6)
begin
data_state <= 99;
delay_counter <= 0;
sync = 1;
end
else delay_counter = delay_counter + 1;
end
endcase
end
endmodule
So with the code as is I get the error
'output or inout port should be connected to a structural net
expression'
.
If I change the outputs in the root module or the inner module to wire I get the error 'the expression on the left hand side should be of a variable type'.
So at this point I have no idea how you nest outputs! Some help would be appreciated!
Thanks
inout ports should be a net type (wire or tri) and not a reg. A reg does not have conflict resolution (when there are two or more active driver). An inout should not be assigned in a procedural block (e.g. always-block, initial-block). It should be a simple assign statement as below. The designer must ensure there is only on active driver on the IO at any point.
assign io_port_name = driver_enable ? io_out_value : 'bz; // io_out_value should be a flop
An output should only be declared an output reg if it is assigned in a procedural block (e.g. always-block, initial-block) within the current module. All other outputs should be output or output wire (these identifiers are synonymous; the former is implicit while the latter is explicit). An should only be assigned within one always. FPGAs allow initial blocks, ASIC/IC does not.
If SystemVerilog is enabled, replace output reg with output logic. logic can be used for flops and single directional nets. logic is not recommended for inout; logic like reg does not have conflict resolution.
The arrays integer data[8]; and integer pd[2]; are SystemVerilog syntax and not compatible with Verilog. Either enable SystemVerilog or change to integer data[0:7]; and integer pd[0:1];
SystemVerilog can be enabled per file by changing the file extension from .v to .sv; recommended. Simulators/synthesizers typically have a switch to force all Verilog to be treated as SystemVerilog; not recommended, refer to the simulator/synthesizer manual if desired to go this route.
I have instantiated a stopwatch module into this multiplexer module. The stopwatch is working as it is supposed to and is producing the expected output. This is also picked up by the instantiated registers. But, if I want to use this data further down the module, it does not work.
Here is the simulation showing my problem:
The values picked up from the stopwatch module are working perfectly. These values are then transferred to the registers regd0, regd1, regd2, regd3 which, instead of displaying the values are displaying 0?
Here is the code that produced the above simulation:
module muxer(
input clock,
input reset,
input [1:0] select,
output a,
output b,
output c,
output d,
output e,
output f,
output g,
output dp,
output [3:0] an
);
reg go_hi, go_start;
wire[3:0] wire_d0, wire_d1, wire_d2, wire_d3; // timer registers that will hold the individual counts
wire[3:0] wire_hd0, wire_hd1, wire_hd2, wire_hd3; //regsiters to hold the "hi" values
reg [3:0] regd0, regd1, regd2, regd3; //registers for LED multiplexing
//instantiate the "hi" module
say_hi sayhi(.clock(clock), .reset(reset), .go(go_hi), .hi_d0(wire_hd0), .hi_d1(wire_hd1), .hi_d2(wire_hd2), .hi_d3(wire_hd3)) ;
//instantiate the stopwatch module
stopwatch timer(.clock(clock), .reset(reset), .start(go_start), .d0(wire_d0), .d1(wire_d1), .d2(wire_d2), .d3(wire_d3) );
always # (select)
begin
case(select)
00: //hi
begin
go_start = 0; //make sure timer module is off
go_hi = 1'b1; //enable go signal to display "hi"
regd0 = wire_hd0; //transfer values to the multiplexing circuit
regd1 = wire_hd1;
regd2 = wire_hd2;
regd3 = wire_hd3;
end
01: //timer
begin
go_hi = 0; //make sure "hi" module is off
go_start = 1'b1; //enable start signal to start timer
regd0 = wire_d0;
regd1 = wire_d1;
regd2 = wire_d2;
regd3 = wire_d3;
end
10: //stop timer
begin
go_hi = 0;
go_start = 1'b0;
end
endcase
end
//The Circuit for 7 Segment Multiplexing -
localparam N = 8; //18 for implementation, 8 for simulation
reg [N-1:0]count;
always # (posedge clock or posedge reset)
begin
if (reset)
count <= 0;
else
count <= count + 1;
end
reg [6:0]sseg;
reg [3:0]an_temp;
reg reg_dp;
always # (*)
begin
case(count[N-1:N-2])
2'b00 :
begin
sseg = regd0;
an_temp = 4'b1110;
reg_dp = 1'b1;
end
2'b01:
begin
sseg = regd1;
an_temp = 4'b1101;
reg_dp = 1'b0;
end
2'b10:
begin
sseg = regd2;
an_temp = 4'b1011;
reg_dp = 1'b1;
end
2'b11:
begin
sseg = regd3;
an_temp = 4'b0111;
reg_dp = 1'b0;
end
endcase
end
assign an = an_temp;
reg [6:0] sseg_temp;
always # (*)
begin
case(sseg)
4'd0 : sseg_temp = 7'b1000000; //display 0
4'd1 : sseg_temp = 7'b1111001; //display 1
4'd2 : sseg_temp = 7'b0100100;// display 2
4'd3 : sseg_temp = 7'b0110000;
4'd4 : sseg_temp = 7'b0011001;
4'd5 : sseg_temp = 7'b0010010;
4'd6 : sseg_temp = 7'b0000010;
4'd7 : sseg_temp = 7'b1111000;
4'd8 : sseg_temp = 7'b0000000;
4'd9 : sseg_temp = 7'b0010000;
4'd10 : sseg_temp = 7'b0001001; //to display H
4'd11 : sseg_temp = 7'b0000111; //to display I
default : sseg_temp = 7'b0111111; //dash
endcase
end
assign {g, f, e, d, c, b, a} = sseg_temp;
assign dp = reg_dp;
endmodule
My guess is that select does not equal 01. You should show that in waves as well.
Here are a couple of other observations.
If you want regd0 to model combinational logic, you should change always #(select) to always #*. Same for d1-d3. Currently, I think you are modeling latches.
In your case statement 10 refers to decimal 10. You probably wanted 2'b10.
While doing some work for my lab in university
I am creating this function where there is a for loop inside another one.
It is not important to know what the method is used for. I just can't figure out why the program doesn't enter the second for loop. This is the code:
public void worseFit(int[] array){
int tempPosition = -1;
int tempWeight = 101 ;
for (int x = 0; x < (array.length - 1); x++){
if (allCrates.getSize() < 1){
Crate crate = new Crate();
crate.addWeight(array[0]);
allCrates.add(crate);
} else{
for( int i = 1; i < (allCrates.getSize() - 1); i++ ){
Crate element = allCrates.getElement(i);
int weight = element.getTotalWeight();
if (weight < tempWeight){
tempWeight = weight;
tempPosition = i;
Crate crate = new Crate();
if (weight + tempWeight <= 100){
crate.addWeight(weight + tempWeight);
allCrates.setElement(i, crate);
} else {
crate.addWeight(weight);
allCrates.setElement(allCrates.getSize(), crate);
} // if
} // if
} // for
} // if
} // for
} // worseFit
Once the program enters the else part of the code it goes straight
away back to the beginning of the first for loop.
Would anyone know how to solve this problem?
There seems to be some discrepancies with the expected values of allCrates.getSize().
If allCrates.getSize() returns 2, it will go to the second for loop, but not run it, as i < allCrates.getSize() - 1 will result in false
You might want to use <= instead of <
Initialize the variable i in your second loop to 0 instead of 1. Because if your getSize() returns 1 the it will not enter the if part and after entering the else part the for loop condition will evaluate to false and hence your for loop will not be executed.
In any programming language (like php, java, javascript etc) is it possible to dynamically create a changing number of variables in a loop, within a given name space?
for example, if I want to create N variables that have random numbers between 1 and 5, which are to be called random1, random2 .. randomN, is it possible to do something like:
loop ( N ){<br>
create variable randomN = random(1,5);<br>
}
In PHP you could use variable variables:
$N = 5;
for ($i = 0; $i != $N; ++$i) {
${"random$i"} = rand(1, 5);
}
In JavaScript, same thing:
var N = 5;
for (var i = 0; i != N; ++i) {
window['random' + i] = Math.round(Math.random() * 5);
}
Though, I would recommend using a "container" to hold those variables, so that they're not created globally.
Or you can use $$, see variable variables.
for ($n = 1; $n <= 5; $n++) {
$varName = 'random' . $n;
$$varName = rand(1, 5);
}
$vars = get_defined_vars();
var_dump($vars);