module processor_testbench (
input [7:0] o_cmd_status_reg,
input o_start_ack,
output reg [7:0] i_transmit_data, // transmit data port
input o_transmit_data_request, // transmit data required
output reg i_rst_n,
output reg i_clk
);
initial begin
i=1'b0;
end
initial begin //-> Where the problem is
#(posedge(o_start_ack));
i=i+1;
if(i==1)
i_transmit_data = 8'bxxx00000;
else if(i==2)
i_transmit_data=8'b00000000;
else if(i==3)
i_transmit_data=8'b11110000;
else if(i==4)
i_transmit_data=8'b00000000;
//stop trasmission #start acknowledge
end
endmodule
I want to see the result (simulation) when the o_start_ack become rising edge.
i_transmit_data is changing
8'bxxx00000 -> 8'b00000000 -> 8'b11110000 -> 8'b00000000
But, the simulation shows only 8'bxxx00000.
Codes that are not used in this case are removed by me.
How can I make i_transmit_data have various value?
Change your second initial block to an always block:
always begin
#(posedge(o_start_ack));
i=i+1;
// ...
The problem with your code is that the initial block only waits for one posedge of the o_start_ack signal. Once it sees the 1st posedge, it sets i=1 and i_transmit_data=8'bxxx00000, then the block stops executing.
Using an always block allows the code to execute every time there is a posedge of o_start_ack.
Related
I am trying to create a uvm type test bench for a phase accumulator which is to be used in a DDS chain. Having this may be an overkill for a simple phase accumulator, but I am new to uvm/SystemVerilog so want to learn how to use the concepts. I have several questions.
My DUT:
module phase_acc #(
parameter PHASE_ACC_WIDTH = 16,
parameter TUNNING_WORD_WIDTH = 8
) (
input wire clk,
input wire reset,
input wire load,
input wire [TUNNING_WORD_WIDTH-1 : 0] tuning_word,
output reg [PHASE_ACC_WIDTH-1 : 0] phase,
output wire cycle_end,
output wire [1:0] phase_quadrant
);
assign phase_quadrant = phase[PHASE_ACC_WIDTH-1:PHASE_ACC_WIDTH-2];
assign cycle_end = (phase + tuning_word) > {PHASE_ACC_WIDTH{1'b1}};
always #(clk) begin
if (reset == 1) begin
phase <= 0;
end else begin
phase <= phase + tuning_word;
end
end
endmodule
Please note that this is not complete and planning to fill it after writing tests.
basic functionality is that the phase_acc counts up by tuning_word at a time. Just before it wraps around, it needs to assert cycle_end. Forget about phase_quadrant for now.
A new tuning_word can be loaded by asserting load.
I have created two classes to monitor signals. One for input stimulus (tuning_word and load) which gets triggered when ever load is one during a clock transition. The other is for phase_acc outputs which contain phase, cycle_end. Since these change at each clock transition, a new object of this type need to be created at each clock edge. Monitor uses two analysis ports to send stimulus packets and output packets to scoreboard.
My first question is, does this design make sense? Most uvm examples I saw have a behavior where after a stimulus is created, the DUT gives a single output which is then verified. (Say a RAM for example). In my case however, the DUT is free running.
If above design is correct, I have my second question.
My code for the monitor is:
class monitor extends uvm_monitor;
`uvm_component_utils(monitor)
function new(string name = "monitor", uvm_component parent = null);
super.new(name, parent);
endfunction
uvm_analysis_port #(acc_stimulus) mon_stimulus_analysis_port;
uvm_analysis_port #(acc_output) mon_output_analysis_port;
virtual reg_if vif;
semaphore sema4;
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db#(virtual acc_if)::get(this, "", "acc_if", vif))
`uvm_fatal("MON", "Could not get vif")
sema4 = new(1);
mon_stimulus_analysis_port = new("mon_stimulus_analysis_port", this);
mon_output_analysis_port = new("mon_output_analysis_port", this);
endfunction
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
forever begin
fork
begin
#(vif.clk);
// output
acc_output out = new;
out.phase = vif.phase;
out.cycle_end = vif.cycle_end;
out.phase_quadrant = cif.phase_quadrant;
`uvm_info(get_type_name(), $sformatf("Monitor found ouout %s", out.convert2str()),
UVM_LOW)
mon_output_analysis_port.write(out);
end
begin
#(vif.clk);
// stimulus
if (vif.ld) begin
acc_stimulus stimulus = new;
stimulus.tunning_word = vif.tuning_word;
stimulus.load = vif.ld;
`uvm_info(get_type_name(), $sformatf("Monitor found stimulus %s",
stimulus.convert2str()), UVM_LOW)
mon_stimulus_analysis_port.write(stimulus);
end
end
join
end
endtask
endclass
But when trying to compile this, I get an error for the line which says:
acc_output out = new;
I am not sure what I am doing wrong there. If I were to do this inside an if condition, for example:
begin
#(vif.clk);
if(vif.clk) begin
// output
acc_output out = new;
Then the error disappears.
I cannot understand what's wrong with the code.
You get the error because you declared the out variable in the middle of a begin/end block, after a statement:
begin
#(vif.clk); // This is a statement
// output
acc_output out = new; // This is a variable declaration
Inside a begin/end block, you must declare all variables before statements.
The error went away when you declared the variable in the if clause because it was the first line of code after the begin keyword. The fact that this was inside an if condition is irrelevant. The key was that you created a new block of code with the begin keyword.
This should also work:
begin
// output
acc_output out = new;
#(vif.clk);
I have 2 Modules. One is Register_File_Rf which is a file of 32 Registers I have created. I want to be able to see what every single register is storing.
Can I do this with $display or $monitor somehow?
Where these should be? In actual code or in Testbench, and how do I get the value in testbench when the stored Data is neither input or output?
module Register(
input Clk,
input [31:0] Data,
input WE,
output reg[31:0] Dout
);
reg [31:0] stored;
// With every Positive Edge of the Clock
always #(posedge Clk)begin
// If Write is Enabled we store the new Data
if (WE)begin
stored <= Data;
Dout <= stored;
end else
Dout <= stored;
end
module Register_File_RF(
input [4:0] Adr1,
input [4:0] Adr2,
input [4:0] Awr,
output reg[31:0] Dout1,
output reg[31:0] Dout2,
input [31:0] Din,
input WrEn,
input Clk
);
integer j;
genvar i;
wire [31:0]Temp_Dout[31:0];
reg W_E [31:0];
// Writing only in the first time R0 Register with 0
initial begin
W_E[0] = 1;
end
// Creating the R0 Register
Register register (.Clk(Clk),.WE(W_E[0]),.Data(0),.Dout(Temp_Dout[0]));
// Creating 30 Registers
for(i = 1; i < 32; i = i + 1)begin:loop
Register register (.Clk(Clk),.WE(W_E[i]),.Data(Din),.Dout(Temp_Dout[i]));
end:loop
// Assigning to Dout1 and Dout2 the Data from a spesific register
always #(Adr1, Adr2) begin
Dout1 = Temp_Dout[Adr1];
Dout2 = Temp_Dout[Adr2];
end
// Wrting Data to a specific register
always #(posedge Clk)begin
//Reseting Write Enable of the register to 0
for (j = 0; j < 32; j = j + 1)begin:loop2
W_E[j] = 0;
end:loop2
if(WrEn)begin
W_E[Awr] = WrEn;
end
end
endmodule
Yes, you can do this with either $display or $monitor.
Typically, $monitor would be called inside an initial block since it should only be called at one time in your simulation. It automatically displays values whenever one of its argument signals changes value.
Unlike $monitor, $display only displays values when it is called; it must be called whenever you want to display a signal value. It can be called in an initial block, but it is often called in an always block.
Regarding when to use either one, it is up to you to decide what you require.
If you are not planning to synthesize your modules, you could place monitor/display inside your design module directly. However, if you plan to synthesize, it might be better to place them in the testbench.
You can use hierarchical scoping to view internal signals from the testbench module. For example, assume you named the instance of the Register_File_RF module in the testbench as dut:
Register_File_RF dut (
// ports
);
always #(posedge Clk) begin
$display($time, " dout='h%x", dut.register.Dout);
end
initial begin
$monitor($time, " dout='h%x", dut.register.Dout);
end
$monitor will display a value every time Dout changes value, whereas $display will show the value at the posedge of the clock.
If your simulator supports SystemVerilog features, you can also use bind to magically add code to your design modules.
I want to write the code of 1-second down counter that get the initial value from outside and count it down till 0. but there is a problem. How can I get the initial value. i tried some ways but ....
here is the code:
module second_counter ( input clk,
input top_num,
output reg [3:0] sec_num
);
parameter clk_frequency = 25;
reg [31:0]cnt;
wire [3:0]sec;
/// how can get the top_num and count it down.
assign sec=top_num;
always #(posedge clk)
begin
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
What you basically need is a reset signal. Just like clock, reset is to be added in the sensitivity list.
After instantiation of module, you must apply a reset signal to initialize all the internal variables and registers of design.
Following code gives you initial value of cnt by reset application. This is an active low reset.
module second_counter ( input clk, input reset, input top_num, output reg [3:0] sec_num );
parameter clk_frequency = 25;
reg [31:0]cnt;
// wire [3:0]sec;
reg [3:0] sec;
///
// assign sec=top_num;
always #(posedge clk, negedge reset)
begin
if(!reset)
begin
cnt<=0; // initialize all internal variables and registers
sec<=0;
end
else
begin
if(sec == 0) // latch input when previous count is completed
sec<=top_num;
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
end
Note that this is an asynchronous reset, means it does not depend on clocking signal. Synchronous reset is the one which only affects the registers at the clock pulse.
Edit:
Regarding to sec, I have modified the code. Now the design latches the inputs for one clock cycle and counts down to zero. Once the counter reaches zero, it again latches the input to re-count to zero.
Note that you cannot do like latching top_num at every clock and counting through zero (since top_num can change at every pulse). For latching at every clock pulse, you need more complex logic implementation.
I am trying using infinite for loop inside generate statement. But the problem is I cannot stop it or exit it using some condition. I used "disable" and "break". Both don't work.
It shows an error :
unexpected token: 'disable'
Please help me solve this problem or suggest an alternative to it. Here is my Verilog code:
module top(a1,a3,wj,d4,d10,d2,dc,dtot);
input [11:0]a1,a3,wj;
input [3:0]d4;
input [9:0]d10;
input [1:0]d2;
input [25:0]dc;
output reg[25:0]dtot;
reg [25:0]dt,error;
reg [11:0]alpha1,alpha3;
genvar i;
generate
for (i=1;i>0;i=i+1-1)begin:test
assign a1[11:0]=alpha1[11:0];
assign a3[11:0]=alpha3[11:0];
calb_top t1(a1,a3,wj,d4,d10,d2,dc,dt,error,alpha1,alpha3);
if(error==26'b00000000000000000000000000)begin
disable test;
//break;
end
end
endgenerate
assign dtot=dt;
endmodule
Verilog generate block are used to describe physical hardware. As such, an inifinite loop in a generate block will require infinite resources.
Any for loop inside a generate statement must be of a fixed and finite size that can be determined during synthesis.
Remember that HDL is not executed sequentially, but describes connections between physical circuits. Since it appears that you only require one instance of the calb_top module, you don't require either the generate block or the for loop.
Edit:
Since you're intending to perform an iterative process, you have two options, as Greg pointed out in his comment below - you can either instantiate a fixed number of calb_top blocks (since an infinite number would require an infinite amount of space) or to re-use the same block some number of times.
Here are some samples. I've haven't sim'd or synthesized them, but they're logically correct.
N-Block solution
module top(a1,a3,wj,d4,d10,d2,dc,dtot,clock,done);
parameter NUM_BLOCKS = 10;
input [11:0]a1,a3,wj;
input [3:0]d4;
input [9:0]d10;
input [1:0]d2;
input [25:0]dc;
output [25:0]dtot;
wire [11:0] a1s [NUM_BLOCKS:0];
wire [11:0] a3s [NUM_BLOCKS:0];
wire [25:0] dt [NUM_BLOCKS-1:0];
wire [25:0] error [NUM_BLOCKS-1:0];
assign a1s[0]=a1;
assign a3s[0]=a3;
genvar i;
generate
for (i=0;i<NUM_BLOCKS;i=i+1)begin:test
calb_top t1(a1s[i],a3s[i],wj,d4,d10,d2,dc,dt[i],error[i],a1s[i+1],a3s[i+1]);
end
endgenerate
assign dtot=dt[NUM_BLOCKS-1];
endmodule
This links together a number of calb_top blocks equal to NUM_BLOCKS, then outputs the result of the final block to dtot. This doesn't do any checks on the error, so you may want to put in your own code to check error[NUM_BLOCKS-1] (the error of the final calb_top).
Single-Block solution:
module top(clock,start,a1,a3,wj,d4,d10,d2,dc,dtot);
input clock;
input start;
input [11:0]a1,a3,wj;
input [3:0]d4;
input [9:0]d10;
input [1:0]d2;
input [25:0]dc;
output reg[25:0]dtot;
wire [25:0]dt,error;
reg [11:0] a1in, a3in;
wire [11:0] alpha1,alpha3;
calb_top t1(a1in,a3in,wj,d4,d10,d2,dc,dt,error,alpha1,alpha3);
always #(posedge clock)
begin
if (start)
begin
a1in <= a1;
a3in <= a3;
end
else
begin
a1in <= alpha1;
a3in <= alpha3;
end
end
always #(posedge clock)
if (start)
dtot <= 0;
else if (error == 0)
dtot <= dt;
else
dtot <= dtot;
endmodule
Each clock cycle, we run one pass through calb_top. If start is 1, then a1 and a3 are used as inputs. Otherwise, the previous outputs alpha1 and alpha3 are used. When error is 0, then dtot is set. Note that I've added clock and start to the port list.
I want to use if-else and for loop inside an always block. I don't want those if-else to be executed again and again, so I don't want to connect always with either posedge clkor negedge clk.
I want them to be executed only once. I not only want to simulate but I want to synthesize on to Spartan Board aswell.
always # (**what I should add here**)
begin
if(condition)
else
end
For simulations to execute some thing once you can use initial but this is not a synthesizable:
reg x;
initial begin
if(condition) begin
x = 1'b0 ;
end
else begin
x = 1'b1 ;
end
end
To answer the general question always #(**what I should add here**) Most modern verilog simulators will allow the use of * which will trigger the block (always begin to end) when any right hand side argument changes of any condition of selection logic.
always #* begin
if(condition)
x = y ;
else
x = ~y ;
end
older simulators would require you to list the variables you needed to trigger on, in a list. always #(condition, y)
If there is only 1 variable being selected an assign on a wire type might be better, but this can not be limited to being 'executed once', but would be a suitable choice from your question. Not sure about suitability for FPGA's though
wire [3:0] x ; //4 bit wire
//(condition) ? value if true : value if false ;
assign x = (condition) ? 4'b1010 : 4'b0100 ;
module oneShot(in, out, enable, reset);
input in;
input enable;
input reset;
output reg out;
reg once_only;
always # (posedge enable) begin
if (reset) begin
once_only <= 0;
end
else if (once_only == 0) begin
out <= calc_out; // or whatever processing you want
once_only <= 1;
end
end
always #(*) begin
// calculate ouput here always
calc_out = 1 + 7 +100+ in;
end
endmodule
You can't have those if statements calculate only once. It's hardware, it'll always calculate. But you can hold the output steady after it's been calculated once. You are still trying to write a software function and put it in to hardware rather than describe hardware which will solve your problem. I can't see that you'll get a decent design this way. Sure you'll be able to make some small pieces and synthesise them (eventually), but a full design??