I am working on project in which I have to read 5 bits binary values from text file. I have to read each 5 bit binary number and then assign them to 5 different 1 bit registers one by one. Moreover i can't use 'memreadb' because my text file is so huge almost 2mb and I think 'memreadb' can't deal with such a huge file because its not working in my case. so can anyone please tell me how to use 'fopen' and 'fread' function to solve my problem because i have not work on file handling in Verilog till now. And can anyone provide me an example similar to my problem?
Thanks,
Sami
You can use $fscanf to read your file one line at a time.
integer status, fd;
reg [4:0] value;
initial begin
fd = $fopen("data_file.dat", "r");
if (!fd) $error("could not read file");
while (!$feof(fd)) begin
status = $fscanf(fd,"%b",value);
// check status, then do what you need to do with value
end
end
Related
I can open a file with
integer fd;
fd = $fopen ("file_to_open.txt", "r");
But if i have multiple files in a directory such as
f1.txt
f2.txt
f3.txt
How can I iterate over these files without explicitly defining their name in my verilog testbench?
In bash, this would be done with:
for f in ./*.txt; do
...
done
Verilog does not have a way of directly interacting with the Operating System a simulation is running on, so it cannot expand file names.
Two alternatives you have in Verilog are:
writing some C code that does this and linking that code through the VPI (difficult)
Creating a bash script that builds your list of files into a text file, then reading that list one line at a time with $fgets or $fscanf. (cumbersome)
This would be much easier if you were using SystemVerilog because it has string data types, and a direct interface to C (DPI)
I'm using readmemh like:
reg [11:0] rom [0:121];
initial $readmemh("x.data", rom);
My x.data file looks like:
line 1: 1
line 2: 10
.
.
.
line 118: 1110101
line 119: 1110110
line 120: 1110111
When I try to use rom[20] during the simulation, I see XXX value. Also, I have checked all rom data values during the simulation, and I saw XXX,XXX,..,XXX
I'm not sure that I used $readmemh in proper way.
When I use your code to read the file, I get warning messages with 2 different simulators. In both cases, the simulator fails to read the file and load the data into the rom variable. If I add the following code:
integer i;
initial for (i=0; i<=121; i=i+1) $displayb(rom[i]);
I see x for all locations in rom. You declared rom as a reg type, and reg types default to x.
The problem is that Line 1:, Line 2:, etc., are incorrect syntax. You need to remove them from the x.data file. Your file should look something like this:
1
10
1110101
1110110
1110111
However, I still get simulator warnings because the simulator interprets 1110101 as a hexadecimal value. Since this value is too large for the 12-bit variable, the simulator does not load it into rom, leaving the value as the default x.
My guess is that your data is really binary format instead of hex. In that case, use $readmemb instead of $readmemh:
initial $readmemb("x.data", rom);
When I make that change, I no longer see x.
Refer to IEEE Std 1800-2017, section 21.4 Loading memory array data from a file for detailed syntax.
Try using the full path to your file. Likely your simulator is not in the same directory as your file.
I need to get waveform data from the wav file,but my code returns not right waveform (i compare my results with waveform from fl studio)
This is my code:
path = "/storage/emulated/0/FLM User
Files/My Samples/808 (16).wav";
waveb = FileUtil.readFile(path);
waveb = waveb.substring((int) (waveb.indexOf("data") + 4), (int)(waveb.length()));
byte[] b = waveb.getBytes();
for(int i= 0; i < (int)(b.length/4); i++) {
map = new HashMap<>();
map.put("value", String.valueOf((long)((b[i*4] & 0xFF) +
((b[i*4+1] & 0xFF) << 8))));
map.put("byte", String.valueOf((long)(b[i*4])));
l.add(map);
}
listview1.setAdapter(new
Listview1Adapter(l));
( (BaseAdapter)listview1.getAdapter()).notifyDataSetChanged();
My results:
Fl studio mobile results:
I'm not sure I can help, given what I know off of the top of my head, but perhaps this will trigger some ideas in your search for a solution.
It looks to me like you are assuming the sound file is 16-bit stereo, little-endian, and that you are only attempting to inspect one track of the stereo frame. Can you confirm this?
There's at least one way this plan could go awry: the .wav header may be an odd number of bytes in length, and you might not be properly parsing frame boundaries as a result. As an experiment, maybe try adding a different increment when you reference the b[] array? For example b[i4 + 1] and b[i4 + 2] instead of b[i4] and b[i4 + 1]. This won't solve the general problem of parsing .wav headers, but it could at least get you closer to understanding the situation.
It sure looks like Java's AudioInputStream is not accessible in Android, and all searches that I have that ask if there is an Android equivalent are turning up unanswered.
I've used AudioTrack for the playback of raw PCM, but I don't know an Android equivalent for reading wav files. The AudioRecord class and read() methods look interesting as the read methods store PCM data in a short array, but I've never used them, and they seem to be hard-coded to the microphone for input.
There used to be a Google Group: andraudio#googlegroups.com. IDK if it is still around. I used to go there and occasionally ask about things.
Maybe there is code you can use from Oboe or libGDX? The latter makes use of OpenAL and is for cross-platform development, with Android as one of the target platforms. I have not looked into either for this question.
If you do find the answer, it would be great to post it as a solution. This seems to be a matter that many have tried to solve and given up on.
As you know $fdisplay can print info into a file. But if you instantiate a module (like a BFM:Bus functional model) several times in the test bench and each of them has $fdisplay, then a problem may occur : Simultaneous access to a file
I my expriene that issue causes a not neat and tidy output file.
So how can I achieve my goal?
Python-Equivalent of my question is here.
P.S. The simulator's console has limitation of what can be aggregated and my logs are somewhat long. So I should print them to file. Also merging all verilog codes into one is not possible at all.(Think how the BFM models are)
If you want all the output from your BFMs to go into a single file, your problem is not with $fdisplay but with $fopen. You need to create a top level function that calls $fopen only if it has not been called before.
integer file=0;
function integer bfm_fopen;
begin
if (file)
bfm_fopen = file;
else begin
file = $fopen("logfile");
bfm_fopen = file;
end
end
endfunction
Then call top_level.bfm_fopen from your BFMs
Before I begin, I must preface by stating that I am a novice when it comes to FORTRAN. I am maintaining a legacy piece of code from 1978. It's purpose is to read in some data values from a file, process the values, and then output the processed values to another text file.
Given the following FORTRAN code:
INTEGER NM,STUBS,I,J,K
PARAMETER (NM=67,STUBS=43)
INTEGER*4 MDS(STUBS,NM)
CALL OPEN$A(A$RDWR,'/home/test/data.txt', MAXPATHLEN,1)
CALL OPEN$A(A$WRIT,'out',11,2)
DO 90 I=1,2
READ(1,82) STUB
!-- data processing --!
WRITE(2,80) STUB,(MDS(I,J),J=1,24)
90 CONTINUE
80 FORMAT(/1X,A24,25I5)
82 FORMAT(1X,A24,25F5,1)
My question is in regards to the WRITE() statement.
I understand that (2,80) refers to the file output stream opened and pointing to the file 'out' and referenced by the numeral 2. I understand that 80 refers to the format statement referenced by label 80.
STUB is used to store the values read from file input 1. These values are what is processed, and saved into MDS(I,J) in the !-- data processing --! section that I have omitted.
Am I correct in assuming that (MDS(I,J),J=1,24) will write 24 integer values to the output file? In other words, looping from 1 to 24?
Yes, you are correct. The syntax (MDS(I,J), J=1,24) is an "implied DO-loop" and is commonly used in situations like this.