How can I use a prepared module in a loop in Verilog? - loops

I am trying to generate 128 parellel XOR gates, and then connecting their outputs to 64 XOR gates in Verilog. I use a module that prepared named "EXOR". My problem is: When I put this module "EXOR" into the loop, program gives syntax error "unexpected token: 'EXOR'". And I want to name the gates exor0, exor1, ... .
How can I solve it?
initial begin
for (i=0; i<128 ; i=i +1 )
EXOR exor[i](.I1(m[2*i]), .I2(m[2*i+1]), .o(t[i]));
end
initial begin
for (i=0; i<64 ; i=i +1 )
EXOR exor[i+128](.I1(t[2*i]), .I2(t[2*i+1]), .o(f[i]));
end
initial begin
for (i=0; i<32 ; i=i +1 )
EXOR exor[i+192](.I1(f[2*i]), .I2(f[2*i+1]), .o(g[i]));
end

To elaborate on Munkymorgy's answer what you're looking for here is a generate loop. 'initial' and 'always' blocks are used for "runtime" constructs. Since you're trying to create an array on instances you want something interpreted at elaboration time.
genvar i;
generate
for (i = 0; i < 64; i = i + 1) begin : gen_loop
EXOR exor(.I1(m[2 * i]), .I2(m[2 * i + 1], .o(t[i]));
end
endgenerate
Two things:
1) The loop variable has to be declared as a 'genvar'
2) The for loop needs to be named. This will be used in the hierarchical name of the instance.

Related

what is the difference between SAS ARRAY and SAS IF-THEN

I have a table with students exams scores;
veriables: name, score1, score2, score3 and gender
wherever there is a missing value in one of the scores,
the score is set to 999.
I want to transform all 999's to missing (.) values.
I realized there are 2 main ways and I would like to know the MAIN difference between them.
As written above, both give the same output:
first:
data try ;
set mis_999 ;
if score1 = 999 then score1 = . ;
if score2 = 999 then score2 = . ;
if score3 = 999 then score3 = . ;
run ;
second (with array):
data array_try ;
set mis_999 ;
array try2{*} score1-score3 ;
do i=1 to dim(try2) ;
if try2(i) = 999 then try2(i) = . ;
end ;
run ;
For that example the main difference is that the code using an array is easier to expand to more variables.
In your first example you have what is referred to as wallpaper code, a lot of code that repeats the same pattern. If you have 500 variables instead of 3 you would need to write 500 statements. But with the array method you would just need to change the list of variables in the array definition. The DO loop would be the same.

Assign an array's value as a dimension to another array in SAS

I've been working on a complicated code and am stuck in the end, where I need to assign one array's value as a dimension parameter to another array in the code. A snapshot from my code :
For example:
array temp_match_fl(3) temp_match_fl1 - temp_match_fl3;
ARRAY buracc_repay(3) buracc_repay1 - buracc_repay3;
ARRAY ocs_repay(3) ocs_repay1 - ocs_repay3;
jj = 0;
do until (jj>=3);
jj=jj+1;
If length(strip(match_flag(jj))) = 1 then do;
temp_match_fl(jj) = match_flag(jj);
end;
Else If length(strip(match_flag(jj))) > 1 then do;
j1 = 0;
min_diff = 99999999;
do until (j1>=length(strip(match_class(jj))));
j1=j1+1;
retain min_diff;
n=substr(strip(match_flag(jj)),j1,1);
If (min_diff > abs(buracc_repay(jj)-ocs_repay(n))) then do;
min_diff = abs(buracc_repay(jj)-ocs_repay(n));
temp_match_fl(jj) = n;
end;
end;
end;
kk=temp_match_fl(jj);
/* buracc_repay(jj) = ocs_repay(kk);*/
buracc_repay(jj) = ocs_repay(temp_match_fl(jj));
end;
run;
Now, I need to be able to assign the value stored in temp_match_fl(jj) array as dimension parameter to another array, how can I achieve that?? None of the last two statements work:
buracc_repay(jj) = ocs_repay(kk);
buracc_repay(jj) = ocs_repay(temp_match_fl(jj));
Can someone please suggest.
Thanks!
Actually your last two statements as written do work. Are you getting an error, or unexpected results? Can you make a simple example like below that shows the problem?
Note that for this to work, it's essential that the value of temp_match_fl(jj) is 1, 2, or 3, because your OCS_REPAY array has three elements. From the code you've shown, it's not clear if that is always true. You don't show the match_flag array.
data want ;
array temp_match_fl(3) temp_match_fl1 - temp_match_fl3 (1 2 3) ;
array buracc_repay(3) buracc_repay1 - buracc_repay3 (10 20 30) ;
array ocs_repay(3) ocs_repay1 - ocs_repay3 (100 200 300) ;
jj=1 ;
kk=2 ;
*buracc_repay(jj) = ocs_repay(kk); *this works ;
put temp_match_fl(jj)= ; *debug to confirm value is 1 2 or 3 ;
buracc_repay(jj) = ocs_repay(temp_match_fl(jj)); *this also works;
put (buracc_repay:)(=) temp_match_fl1=; *check output ;
run ;

synthesizable way to load initial values in verilog

I would like to write a module that uses some coefficients that are loaded from a file.
For example:
reg [3:0] coeffs[0:1];
reg [6:0] ans;
always #(posedge clk) begin
if (!reset) begin
coeffs[0] <= 3;
coeffs[1] <= 2;
ans <= 0;
end
else begin
ans <= coeffs[0] * coeffs[1];
end
end
I would like to replace the values 3 and 2 by values that I can modify in a file, and provide the file during synthesis.
Obviously, this file will only assign initial values to the registers.
I don't want it to be a block ram, I want it to be like independent registers.
Just to clarify, I need the solution to be very generic, because I intent to use it in many modules that are doing the same thing, but with a different number of coefficients.
Meaning, in the end I wish to have a generic module that receives as a parameter a file name that stores the coefficients, and the number of coefficients and their width, and generates a code using those parameters.
I have tried readmemh but I understood it is only synthesizable to initiate a memory.
Any suggestions?
Thanks.
Here's a suggestion: put the statements initialising the array coeffs in an include file, eg
coeffs.v:
coeffs[0] <= 3;
coeffs[1] <= 2;
code:
reg [3:0] coeffs[0:1];
reg [6:0] ans;
always #(posedge clk) begin
if (!reset) begin
`include "coeffs.v"
ans <= 0;
end
else begin
ans <= coeffs[0] * coeffs[1];
end
end
An include file is included at compile time. So, your synthesiser will insert the contents of the file in the right place in the design. You could then manage the files using your operating system.
I am happy to stand corrected, but apart from 'Trickery' (Include files, define files, running a script generating such before synthesis) I am not aware of any method where you can load plain numbers from a file for synthesis.
I admit it a is problem waiting for a solution.
If only to prevent major embarrassment when your chip comes back from the manufacturer and you find the boot-rom is completely empty.... As if that ever happened where I worked (rolls eyes) Fixing requires only a single (contact) layer change but the lower layer masks are the most expensive).
Using parameter to pass the initial value is better option.
module A
#( parameter INITIAL_VALUE_COEFFS_0 = 3,
parameter INITIAL_VALUE_COEFFS_1 = 2)
( /* ignore it */ );
reg [3:0] coeffs[0:1];
reg [6:0] ans;
always #(posedge clk) begin
if (!reset) begin
coeffs[0] <= INITIAL_VALUE_COEFFS_0;
coeffs[1] <= INITIAL_VALUE_COEFFS_1;
ans <= 0;
end
else begin
ans <= coeffs[0] * coeffs[1];
end
end
endmodule

(HCS12 Microcontroller: Assembly Language) Which branch is appropriate for this loop?

What I'm really stuck on is how I'm supposed to make this loop properly I tried doing every combination for each branch but it either never stops or it stops at the wrong number of loops (supposed to stop after amount of values in RPN_START). I even tried what I did in a previous lab which also failed to work so I'm completely lost as to how I'm supposed to get this program to loop. I understand that the RPN_OUT is the end pointer of the array so I tried putting RPN_START with CPY to compare the values but doing that made it stop after one loop. So I don't know at all which branch I'm supposed to use. Any help/tips/advice would be greatly appreciated. Thank you so much!
ORG DATA
;RPN_IN FCB $06,$03,$2F,$04,$2A,$02,$2B ; 63/4*2+=10
;RPN_IN FCB $05,$01,$02,$2B,$04,$2A,$2B,$03,$2D ; 512+4*+3-
;RPN_IN FCB $02,$03,$2A,$05,$2A,$02,$2F,$01, $2B ; ( ( (2 * 3) * 5) / 2) + 1
RPN_IN FCB $11,$10,$2F,$15,$2A ; ( (11 / 10) ) * 15
RPN_OUT RMB 1
RPN_START FDB RPN_IN ; Pointer to start of RPN array
RPN_END FDB RPN_OUT ; Pointer to end of RPN array
ANSWER RMB 1
TEMP FCB $00
ORG PROG
Entry: ; KEEP THIS LABEL!!
LDS #PROG
LDX #RPN_IN
LOOP:
TFR X,A
LDAA X
...
PSHA
RET:
INX
CPX #RPN_OUT
BNE LOOP
PULA
STAA ANSWER

Concatenation operator in System verilog in a loop

I am trying to do the following : concat = {concat[7:0],clk} inside a forever loop as below :
bit [7:0] concat;
concat = 0;
forever begin
#(posedge clk);
concat = {concat[7:0],clk};
end
I wanted to know what value will it contain after 8 clock iterations at any point of time, if the initial value of concat = 0.
Can it be different from 'hAA or 'h55 at any point of time?
You can not just write concat = 0; you should either assign concat = 0; or
initial begin
concat = 0;
end
Forever can not be used like that, the only two top levels you're allowed are initial and always. You want some thing like the following for a simulation:
initial begin
forever begin
#(posedge clk);
concat = {concat[6:0],clk};
end
end
If you are writing for synthesis then you might want to imply a flip-flop:
always #(posedge clk) begin
concat = {concat[6:0],clk};
end
Once you have fixed your RTL it should be easy to try out on EDA Playground.
Since you have #(posdege clk), clk will always be 1 (or x) when evaluating the RHS of the assignment. So concat will be 'h00, 'h01, 'h03, 'h07, 'h17, ...
Also note that if any other thread tries to read concat on the same positive edge of clk, you have a race condition, so please use a NBA to make the assignment.

Resources