I was trying to understand how we are generating verilog code out of "for" loop in chisel.
Generally verilog code used to unroll body as many time as loop progress but here in chisel it's only unrolling it once.
val io = new Bundle {
val a = UInt(INPUT, 2)
val output = UInt(OUTPUT, 2)
}
io.output := UInt(0)
for(j <- 0 to 4){
io.output := io.a
}
Corresponding verilog code for the above program is :
module LutSimpleALU(
input [1:0] io_a,
output[1:0] io_output
);
assign io_output = io_a;
endmodule
it would be very helpful if someone can tell how for loop is working.
Your for loop is doing the same thing for each iteration. You aren't using the "j" iterator variable anywhere, so this is what it expands to:
io.output := io.a
io.output := io.a
io.output := io.a
io.output := io.a
The semantics here is that the last writer wins, so the last statement of "io.output = io.a" would be the final value. In fact, the previous three statements mean nothing, so they would be pruned from the graph.
Related
Hi I have simplified the problem to a method that simply copies the elements of one array to another array. My problem is that the final assert verifies yet the initial assert fails to verify even though I have a guard to ensure that initial assert only applies after the first time the loop is entered. Hence I think the final assert should imply the initial assert.
Any help much appreciated.
method simpImp(a:array<int>) returns (r:array<int>)
{
print "a ",a[..],"\n";
r := new int[a.Length];
var i:nat := 0;
while (i< a.Length)
decreases a.Length - i
invariant a.Length >= i
{
if (i> 0) { print " bool ",r[i-1] == a[i-1],"\n";}
else {print "*i ",i,"\n";}
//if (i> 0) { assert r[i-1] == a[i-1]; } //Fail
//assert (i>0) ==> r[i-1] == a[i-1]; //Fail
r[i] := a[i];
i:= i +1;
assert r[i-1] == a[i-1];
}
}
method Main() {
var a:array<int> := new int[5];
a[0],a[1],a[2],a[3],a[4] := 10,2,30,4,3;
var iny:= simpImp(a);
print "r ",iny[..],"\n";
}
The issue is that you need to add something to your loop invariant to "remember" any facts you need to carry between iterations. Dafny analyzes the loop body in isolation, assuming only the loop invariants at the beginning of the body. So unless you add the fact to the loop invariant, it will be "forgotten" by Dafny.
In your simplified example, adding
invariant i > 0 ==> r[i-1] == a[i-1]
to the loop causes the program to verify.
You can read more about loop invariants in the second half of this answer. Note that that discussion is phrased in terms of establishing that loop invariants are preserved, but the reasoning is mostly identical to trying to establish that an assertion inside the loop body is valid. Please feel free to ask further questions!
I'm using free Pascal 2.6.4 and I created this code. It's a program that asks for number which represents line in file. Everything works except one thing. When I want to display 1. line it stops with "exitcode 217". Why?
Program FileTruncate;
uses
SysUtils;
label znova;
const
filename = 'C:\Users\KVIKY\Desktop\Pascal\Projects\FileHandling\test.txt';
var
myfile: text;
line: string;
counter:integer;
position:double;
begin
znova:
Writeln('Zadaj cislo riadku: ');
Readln(position);
if position=0 then exit;
if position>26 then exit;
Assign(myfile, filename);
Reset(myfile);
counter:=0;
Repeat
inc(counter);
readln(myfile);
until counter = position-1;
readln(myfile, line);
Close(myfile);
writeln(line);
Writeln('Stlacte enter pre pokracovanie.');
Writeln('Zadajte 0 pre ukoncenie programu.');
readln;
goto znova;
end.
Because when position is 1, your repeat-until condition will never be met (because your counter=1 and position-1 is zero, so counter = position-1 will never happen).
counter represents the line before the target, so...
Instead, you could initialize differently:
counter := -1
or, better, change your loop to a while-do:
while counter < position-1 do
because you have a readln within the loop
I am trying to encode conditional behavior for Verilog statements in a generate loop. For example, the code below returns an error.
module <something> (out);
parameter [4:0] someParam = 0;
output [5:0] out;
genvar l, m;
for(l=0; l<5; l=l+1) begin:STAGE_1
m = 0;
if(someParam[l] < 2)
m = l+2;
else begin
m = l-2;
end
if (m>16) assign out[l] = 1'b0;
else assign out[l] = 1'b1;
end
endmodule
The problem is that the variable m is not a constant and the code errors out. Is there any way I can use compile time variable inside a generate statement which would allow some functionality like the variable m above?
Thanks.
I didnt understand what you intended to calculate due to some errors in your code.
In general, for you to use a parameter in a statement you can use an always block with a if statement as following:
module <something> (out);
parameter [4:0] someParam = 0;
output out; // in this case out is only one bit. it can be more of course.
integer l,m; // no need for genver when not using generate
always (*) begin
m = 0;
for (l=0; l<5; l=l+1) begin:STAGE_1
if (someParam[l] == 1'b1) // nothing good comes for checking if a bit is less then 2
m = m+1; // just counting bits in someParam. doing +-2 does not make sense.
end
if (m >= 3)
out = 1'b1;
else
out = 1'b0;
end
The above is a majority function.
Good luck
I seem to have some issues anytime I try anything with I/O for verilog. Modelsim either throws function not supported for certain functions or does nothing at all. I simply need to read a file character by character and send each bit through the port. Can anyone assist
module readFile(clk,reset,dEnable,dataOut,done);
parameter size = 4;
//to Comply with S-block rules which is a 4x4 array will multiply by
// size so row is the number of size bits wide
parameter bits = 8*size;
input clk,reset,dEnable;
output dataOut,done;
wire [1:0] dEnable;
reg dataOut,done;
reg [7:0] addr;
integer file;
reg [31:0] c;
reg eof;
always#(posedge clk)
begin
if(file == 0 && dEnable == 2'b10)begin
file = $fopen("test.kyle");
end
end
always#(posedge clk) begin
if(addr>=32 || done==1'b1)begin
c <= $fgetc(file);
// c <= $getc();
eof <= $feof(file);
addr <= 0;
end
end
always#(posedge clk)
begin
if(dEnable == 2'b10)begin
if($feof(file))
done <= 1'b1;
else
addr <= addr+1;
end
end
//done this way because blocking statements should not really be used
always#(addr)
begin:Access_Data
if(reset == 1'b0) begin
dataOut <= 1'bx;
file <= 0;
end
else if(addr<32)
dataOut <= c[31-addr];
end
endmodule
I would suggest reading the entire file at one time into an array, and then iterate over the array to output the values.
Here is a snippet of how to read bytes from a file into a SystemVerilog queue. If you need to stick to plain old Verilog you can do the same thing with a regular array.
reg [8:0] c;
byte q[$];
int i;
// Read file a char at a time
file = $fopen("filename", "r");
c = $fgetc(file);
while (c != 'h1ff) begin
q.push_back(c);
$display("Got char [%0d] 0x%0h", i++, c);
c = $fgetc(file);
end
Note that c is defined as a 9-bit reg. The reason for is that $fgetc will return -1 when it reaches the end of the file. In order to differentiate between EOF and a valid 0xFF you need this extra bit.
I'm not familiar with $feof and don't see it in the Verilog 2001 spec, so that may be something specific to Modelsim. Or it could be the source of the "function not supported."
I have a simple verilog program that increments a 32 bit counter, converts the number to an ASCII string using $sformat and then pushes the string to the host machine 1 byte at a time using an FTDI FT245RL.
Unfortunately Xilinx XST keeps optimizing away the string register vector. I've tried mucking around with various initialization and access routines with no success. I can't seem to turn off optimization, and all of the examples I find online differ very little from my initialization routines. What am I doing wrong?
module counter(CK12, TXE_, WR, RD_, LED, USBD);
input CK12;
input TXE_;
output WR;
output RD_;
output [7:0] LED;
inout [7:0] USBD;
reg [31:0] count = 0;
reg [7:0] k;
reg wrf = 0;
reg rd = 1;
reg [7:0] lbyte = 8'b00000000;
reg td = 1;
parameter MEM_SIZE = 88;
parameter STR_SIZE = 11;
reg [MEM_SIZE - 1:0] str;
reg [7:0] strpos = 8'b00000000;
initial
begin
for (k = 0; k < MEM_SIZE; k = k + 1)
begin
str[k] = 0;
end
end
always #(posedge CK12)
begin
if (TXE_ == 0 && wrf == 1)
begin
count = count + 1;
wrf = 0;
end
else if (wrf == 0) // If we've already lowered the strobe, latch the data
begin
if(td)
begin
$sformat(str, "%0000000000d\n", count);
strpos = 0;
td = 0;
end
str = str << 8;
wrf = 1;
strpos = strpos + 1;
if(strpos == STR_SIZE)
td = 1;
end
end
assign RD_ = rd;
assign WR = wrf;
assign USBD = str[87:80];
assign LED = count[31:24];
endmodule
Loading device for application
Rf_Device from file '3s100e.nph' in
environment /opt/Xilinx/10.1/ISE.
WARNING:Xst:1293 - FF/Latch str_0
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
WARNING:Xst:1896 - Due to other
FF/Latch trimming, FF/Latch str_1
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
WARNING:Xst:1896 - Due to other
FF/Latch trimming, FF/Latch str_2
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
The $sformat task is unlikely to be synthesisable - consider what hardware the compiler would need to produce to implement this function! This means your 'str' register never gets updated, so the compiler thinks it can optimize it away. Consider a BCD counter, and maybe a lookup table to convert the BCD codes to ASCII codes.
AFAIK 'initial' blocks are not synthesisable. To initialize flops, use a reset signal. Memories need a 'for' loop like you have, but which triggers only after reset.