verilog behavioral RTL to structural - counter

I been assigned to manually convert the below RTL into its structural equivalent. I don't understand how you'd convert it. What's the structural description for this code in verilog? What steps should I take?
module cou(
output reg [7:0] out,
input [7:0] in,
input iti,
input c,
input clock);
always #(posedge clock)
if (iti == 1)
out <= in;
else if (c == 1)
out <= out + 1;
endmodule

Here is the basic process:
always #(posedge clock) tells you you have positive-edge D-flip-flops without an asynchronous reset or set.
out is the only value being assigned within the always statment. The size of out tells you the number of flops needed.
Drawing a component level schematic diagram can help visualize the structural logic.
Now all that is needed to figure out is the combination logic to the flop's D pin. I'll give you a clue that it can be done using only muxes and an adder.

Related

how to define the input and output for the interface in systemverilog

Here I have a simple example below.
module A(o,clk,rst,i);
output o;
input i,clk,rst;
...
endmodule
and here is an interface class definition below.
interface my_if(input bit clk);
logic o,rst,i;
wire clk;
clocking cb#(posedge clk);
input o; // why input here ?
output i,rst; // why output here ?
endclocking
...
endinterface
My question is how to decide the signal inside cb is input or output ??
Thank you !
There are many uses of input/output in SystemVerilog, which can be confusing.
For ports, they the flow of data across a boundary. For a clocking block, they represent whether a signal is passively being sampled, or actively driven. Depending on the situation, it is perfectly reasonable to have a port declared as an output, and the same signal declared as a clocking block input.

Non-blocking assignment to ref parameter

I would like to understand how tasks in System Verilog work. I thought that a task was just a way of naming and parametrising a bit of code that could otherwise appear enclosed between a begin and an end. However, the way that the parameters work is non-obvious.
Say I want to factor out instances of non-blocking assignments from a module. I might do something like the following, thus reaching the point where there are two instances of the same task that differ just in the parameters (ff_0 and ff_1).
module test_inlined;
bit clk;
int count = 0;
logic [7:0] x, y, z;
task automatic ff_0;
#(posedge clk);
y <= x;
endtask
task automatic ff_1; // really same task as ff_0 to within variable renaming
#(posedge clk);
z <= y;
endtask
always
ff_0;
always
ff_1;
always #(posedge clk)
$strobe("%d: x=%d, y=%d, z=%d", count, x, y, z);
always
#5 clk = !clk;
always #(posedge clk)
begin
x <= count;
count ++;
if (count > 20) $finish;
end
endmodule
It would be trivial to instead place the factored out assignments (aka flip-flops) into two instantiations of the same module, so it would make sense for it to be also possible to express the same functionality in terms of two instances of the same task.
The following does not work because out is supposedly automatic, or that is what Modelsim claims. I do not see why it would be since it is fairly obviously a reference to a static member of a module?
task automatic ff (ref logic [7:0] out, ref logic [7:0] inp, ref bit clk);
#(posedge clk);
out <= inp;
endtask
module test_broken;
bit clk;
int count = 0;
logic [7:0] x, y, z;
always
ff(y, x, clk);
always
ff(z, y, clk);
// .... same as before
endmodule
It does make sense that the tasks need to be automatic to use ref parameters because then there is no need to worry about their lifetime. It is less clear why only blocking assignments to an automatic variable would be allowed. It is not like there is any obvious need for auto variables to go away while there are pending non-blocking assignments?
How do I factor out non-blocking assignments into a task, please? Many thanks in advance.
The problem is that task cannot assume anything about the storage classification of the variable passed to it. The code generated for the task has to work for any kind of storage, so passing by ref has to take on the pessimistic set of restrictions.

Parameterized Modules (SystemVerilog)

I have read the book "Digital Design and Computers Architecture" by David Harris and I have a question about SystemVerilog examples in this book. After the introduction in the "parameterized construction", which is # (parameter ...), this operator is used almost in every example.
For example, the "subtractor" module from this book:
module subtractor #(parameter N = 8)
(input logic [N - 1:0] a,b,
output logic [N - 1:0] y);
assign y = a - b;
endmodule
What's the reason of using N in this code?
Can't we just write the following?:
input logic [7:0] a,b,
output logic [7:0] y);
Moreover, such parameters are used in almost every example further in the book but, as for me, there is no reason for using it. We can set the number of bits directly in square brackets without using additional "parameters".
So, what is the reason of such form of coding above?
The use of parameters serves a number of purposes.
It is always a better programming practice to use a symbolic name associated with a value than using a literal value directly. DATA_WIDTH instead of N would have been a more appropriate example. This documents the meaning of the value.
When a change to that value is needed, you have a single place to make that change, and less chance that you'll miss a change, or change an unintended value.
The use of parameters allows you to re-use the same code in many different places by creating a template and then overriding the parameter values as needed.

Why does this statement introduce memory?

I'm learning SystemVerilog and today my lecturer warned us against accidentally introducing memory into combinational systems. He used the following code as an example of this:
module gate(output logic y, input logic a);
always_comb
if(a)
y = '1;
endmodule
However, I don't understand why this presents a problem. As far as I can see, this is just a simple buffer. In what way does this code introduce memory into the system?
At the beginning of the simulation if a == 0 the value of y will be '0. If later a == 1'b1 then y will become '1. What value do you expect y to have when later on a == 0?
The answer to this question is that it will retain its previous value: '1. That is not the behaviour of combinational logic, whose output by definition only depends on the current state of the inputs, not on their previous states. In order to implement the behaviour you have described, the synthesiser will need a component with state, with storage, with memory. It will fulfill this by using a latch.

which procedural block executed first, in SystemVerilog?

If I have both alwas_comb and always_ff in a single module, which one executed first?.
for example, I have seen this code in a book but I am confused about the functionality. for example, if WE=0 what will be the value of Qout?
module SyncRAM #(parameter M = 4, N = 8)(output logic [N-1:0] Qout,
input logic [M-1:0] Address, input logic [N-1:0] Data, input logic clk, WE);
logic [N-1:0] mem [0:(1<<M)-1];
always_comb
Qout = mem[Address];
always_ff #(posedge clk)
if (~WE)
mem[Address] <= Data;
endmodule
Any help about the truth table of this code is appreciated,
regards
The specific answer to your question is that Qout will just track the value of mem[Address]. In other words, on the rising edge of the clock, if WE is 0, Qout will be driven with the value written to the memory. This is because the memory will behave like a bank of flip-flops, while the Qout output will behave as if it is directly connected to the Q output of a bank of flip-flops.
The order of the execution of the two always blocks is deterministic, because Qout is driven using a blocking assignment (=), whereas the memory is written to using a non-blocking assignment (<=). See the answer here for much more detail.