I'm new in SystemVerilog and I would like to verify the value inside generate memories.
generate
genvar g0, j;
for( g0 = 0; g0 < NB_CFGDUMP_SLAVE; g0 = g0 + 1)
begin : g_slave
cfgdump_chiplet slave (
.rst_n (presetn),
.clk (pclk),
.cfg_id (8'(g0)), //CONV_STD_LOGIC_VECTOR(g0, 8)),
.data_in (data_in),
.shift (shift),
.data_out (s_data_cfgdump_to_apb[g0]),
.cfgdump_addr (s_cfgdump_addr[g0]),
.cfg_data (s_cfg_data[g0]),
.cfg_write (s_cfg_write[g0]),
.read_data0 (s_read_data[g0][0][33:0]),
.read_data1 (s_read_data[g0][1][33:0]),
.read_data2 (s_read_data[g0][2][33:0]),
.read_data3 (s_read_data[g0][3][33:0]),
.read_data4 (s_read_data[g0][4][33:0]),
.read_data5 (s_read_data[g0][5][33:0]),
.read_data6 (s_read_data[g0][6][33:0]),
.read_data7 (s_read_data[g0][7][33:0]),
.read_data8 (s_read_data[g0][8][33:0]),
.read_data9 (s_read_data[g0][9][33:0]),
.read_data10 (s_read_data[g0][10][33:0]),
.read_data11 (s_read_data[g0][11][33:0]),
.read_data12 (s_read_data[g0][12][33:0]),
.read_data13 (s_read_data[g0][13][33:0]),
.read_data14 (s_read_data[g0][14][33:0]),
.read_data15 (s_read_data[g0][15][33:0]),
.wr_ready (16'(1)), // ACK write from register
.cfg_sel (s_cfg_sel[g0])
);
for( j = 0; j < nb_target_by_slave; j = j + 1)
begin : g_ram
ram ram_i (
.clk (pclk),
.we (s_cfg_write[g0]),
.sel (s_cfg_sel[g0][j]),
.address (s_cfgdump_addr[g0]),
.datain (s_cfg_data[g0]),
.dataout (s_read_data[g0][j][31:0])
);
//end
// Redirection du ready sur le bit de poid fort du bus de lecture
assign s_read_data[g0][j][33] = s_cfg_sel[g0][j];
// Redirection du code d'erreur sur le bit de poid 32 du bus de lecture
assign s_read_data[g0][j][32] = 1;
I try to dump the values of each RAM without success or find a solution to verify that the read value is the expected. Someone could help me?
You can run your testcase in GUI mode (cadence) and probe all memory. Than look in to memory viewer. You can easily debug memory data using memory viewer.
You can use -gui command line option to run in GUI mode. Than create probe by going in to design browser and select your memory and right click on it and create probe.
Related
I'm using the library bcm2835 1, it works, I can see on the terminal how plots 126 data information from a sensor but from that point on I recieve this:
bcm2835_init: gpio mmap failed: Cannot allocate memory
Does anyone know what is the problem or how to solve it?I think it's due to the library but not sure how to solve it.
I'm using SPI for reciving the data
#include <bcm2835.h>
#include <stdio.h>
char n = 0;
void escriure_csv(char valor){
}
int main()
{
FILE * fp;
fp = fopen ("file.csv", "w+");
for(int i=0;i<130;i++){
bcm2835_init();
bcm2835_spi_begin();
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_1024);
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
uint8_t send_data = 0xB3; //ens dona igual perque nomès ens interesa el que torna
uint8_t read_data = bcm2835_spi_transfer(send_data);
//printf("Read back from SPI: 0x%02X.\n", read_data);
//transformem al que volem
//els canvis seran mV per lo tant enlloc de *2.5 hi fem fer 2
uint8_t mV = (read_data*250)/1024; //en cas que tornes un 0 es perque el resultat es - o 0.
printf("mV: %u\n", mV);
n+=1;
fprintf(fp,"%d",mV);
fprintf(fp,"\n");
//escriure_csv(mV);
}
fclose(fp);
return 0;
}
As one of the comments said the problem here was that I was initializinf the SPI every iteration, I had to put it outside the for loop.
This is my first post on StackOverflow.
I'm a Verilog newbie, though I have significant experience with Python, C, and C++. I am using Icarus Verilog version 10.1.1 on Windows 10, and am trying to write a dynamic memory allocator. For some reason, when this command is run:
iverilog dynmem.v dynmem_test.v -o dynmem_test.out
the following is outputted:
Assertion failed!
Program: c:\iverilog\lib\ivl\ivl.exe
File: ../verilog-10.1.1/pform.cc, Line 333
Expression: lexical_scope
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
What is the problem with my code, and should I submit a bug report for this?
dynmem.v:
`define WORD_SIZE 32
`ifndef DYNMEM_SIZE // size of dynamic memory in words
`define DYNMEM_SIZE 16384*8/WORD_SIZE // 16 KB
`endif
`define __DYNMEM_BIT_SIZE WORD_SIZE*DYNMEM_SIZE-1 // size of dynamic memory in bits
reg [__DYNMEM_BIT_SIZE:0] dynmem; // dynamic memory
reg [DYNMEM_SIZE:0] allocated; // bitvector telling which words are allocated
reg mutex = 0;
module dynreg(address,
ioreg,
read_en,
write_en,
realloc_en);
output reg [WORD_SIZE-1:0] address;
output reg [WORD_SIZE-1:0] ioreg;
output reg read_en; // rising edge: put word stored at location address into ioreg
output reg write_en; // rising edge: put word stored in ioreg into location address
output reg realloc_en; // rising edge: if ioreg=0, free memory, otherwise reallocate memory into buffer of size ioreg.
task malloc; // allocate dynamic memory
output reg [WORD_SIZE-1:0] size;
output reg [WORD_SIZE-1:0] start;
unsigned integer size_int = size; // convert size to integer
reg flag1 = 1;
while (mutex) begin end // wait on mutex
mutex = 1; // acquire mutex
// loop through possible starting locations
for (index=size_int-1; (index < DYNMEM_SIZE) && flag1; index=index+1) begin
// check if unallocated
reg flag2 = 1;
for (offset=0; (offset < size_int) && flag2; offset=offset+1)
if (allocated[index-offset])
flag2 = 0;
if (flag2) begin // if memory block is free
start = index;
flag1 = 0; // exit loop
end
end
// mark as allocated
for (i=0; i<size; i=i+1)
allocated[start-offset] = 1;
mutex = 0; // release mutex
endtask
task freealloc;
output reg [WORD_SIZE-1:0] size;
output reg [WORD_SIZE-1:0] start;
while (mutex) begin end // wait on mutex
mutex = 1; // acquire mutex
// deallocate locations
for (index=start; index > 0; index=index-1)
allocated[index] = 0;
mutex = 0; // release mutex
endtask
// internal registers
unsigned integer start; // start address
unsigned integer size; // block size
unsigned integer address_int; // address register converted to int
initial begin
// allocate memory
size = ioreg;
malloc(size, start);
end
always #(posedge(read_en)) begin
// read memory into ioreg
address_int = address;
ioreg[WORD_SIZE-1:0] = dynmem[8*(start+address_int)-1 -:WORD_SIZE-1];
end
always #(posedge(write_en)) begin
// write memory from ioreg
address_int = address;
dynmem[8*(start+address_int)-1 -:WORD_SIZE-1] = ioreg[WORD_SIZE-1:0];
end
always #(posedge(realloc_en)) begin
unsigned integer ioreg_int = ioreg; // convert ioreg to integer
reg [WORD_SIZE-1:0] new_start; // new start address
if (ioreg_int != 0) begin // if memory is to be reallocated, not freed
malloc(ioreg, new_start); // allocated new memory
// copy memory
for (i=0; i<size; i=i+1)
dynmem[8*(new_start+i)-1 -:WORD_SIZE-1] = dynmem[8*(start+i)-1 -:WORD_SIZE-1];
end
freealloc(size, start); // free previous memory
// update registers
size = ioreg_int;
start = new_start;
end
endmodule
dynmem_test.v:
module testmodule();
$monitor ("%g ioreg1=%b ioreg2=%b",
$time, ioreg1, ioreg2);
reg [WORD_SIZE-1:0] address1, address2;
reg [WORD_SIZE-1:0] ioreg1=5, ioreg2=10;
reg read_en1, read_en2;
reg write_en1, write_en2;
reg realloc_en1, realloc_en2;
#1 dynreg dr1(address1, ioreg1, read_en1, write_en1, realloc_en1);
#1 dynreg dr2(address2, ioreg2, read_en2, write_en2, realloc_en2);
address1 = 0;
ioreg1 = 23;
#1 write_en1 = 1;
write_en1 = 0;
address1 = 2;
ioreg1 = 53;
#1 write_en1 = 1;
write_en1 = 0;
address1 = 0;
#1 read_en1 = 1;
read_en1 = 0;
address1 = 2;
#1 read_en1 = 1;
read_en1 = 0;
#1 $finish;
endmodule
UPDATE: C:\iverilog\lib\verilog-10.1.1 doesn't exist, and, in fact, I searched in C:\iverilog for pform.cc and found no results. Strange.
#1 dynreg dr1(address1, ioreg1, read_en1, write_en1, realloc_en1);
Using a delay (#1) on an instance declaration is probably confusing Icarus as much as it's confusing me. (What exactly is supposed to get delayed? Does the instance not exist for one simulation step?)
Remove those delays, and put all of the code in your testbench following those two instance declarations into an initial block.
For what it's worth, dynreg is probably not synthesizable as written. It has no clock input, and it contains several loops which cannot be unrolled in hardware.
UPDATE: C:\iverilog\lib\verilog-10.1.1 doesn't exist, and, in fact, I searched in C:\iverilog for pform.cc and found no results. Strange.
This path is probably referring to the location of the code on the developer's computer where your copy of Icarus was compiled. Unless you plan on trying to fix the bug that caused this crash yourself, you can safely ignore this.
I have created a simple module that I replicate several times using the Verilog generate statement. However, it seems that the generate statement somehow effects variable assignment in the module. Here's the code:
module test();
timeunit 10ns;
timeprecision 1ns;
wire[3:0] out;
reg[3:0] values[0:4] = {5, 6, 7, 8, 9};
logic clk;
generate
genvar i;
for (i=0; i < 5; i++) begin: M1
MUT mut(
.out,
.in(values[i]),
.clk
);
end
endgenerate
initial begin
#1 clk = 0;
$monitor("%b %b %b %b %b\n", M1[0].mut.out, M1[1].mut.out, M1[2].mut.out, M1[3].mut.out, M1[4].mut.out);
#10 $stop;
end
always #1 clk++;
endmodule
module MUT(output [3:0] out, input [3:0] in, input clk);
reg[3:0] my_reg[0:7];
assign out = my_reg[7];
always #(posedge clk) begin
my_reg[7] <= in; //5
end
endmodule
The expected output of this test program would be 0101 0110 0111 1000 1001, however the output I get is xxxx xxxx xxxx xxxx. It seems that the values in the values variable in the test module are not getting assigned to the out variable in the MUT module. However, when I replace my_reg[7] <= in; with say, my_reg[7] <= 5;, the code works as expected. The code also works when I assign directly to out (after declaring it as register) i.e. out <= in;. There's no problem if I replicate the MUT modules 'manually' without using any generate statements.
You are not connecting the outputs to separate wires. So they are implicitly tied together(like how it did for clock) resulting multiple drivers for a bit.
Just add
wire[3:0] out[0:4];
generate
genvar i;
for (i=0; i < 5; i++) begin: M1
MUT mut(
.out(out[i]), // Connect to different wires
.in(values[i]),
.clk
);
end
endgenerate
Try to initialize clk variable with 0.
I was looking into spi driver in u boot , here is a small snippet from
omap_spi.c
void spi_init(void)
{
gpMCSPIRegs = (MCSPI_REGS *)MCSPI_SPI1_IO_BASE;
unsigned long u, n;
/* initialize the multipad and interface clock */
spi_init_spi1();
/* soft reset */
CSP_BITFINS(gpMCSPIRegs->SYSCONFIG, SPI_SYSCONFIG_SOFTRESET, 1);
for (n = 0; n < 100; n++) {
u = CSP_BITFEXT(gpMCSPIRegs->SYSSTATUS,
SPI_SYSSTATUS_RESETDONE);
if (u)
break;
}
...more code
}
here in
omap_spi.h
#define CSP_BITFINS(var, bit, val) \
(CSP_BITFCLR(var, bit)); (var |= CSP_BITFVAL(bit, val))
my confusion here is that when they do soft reset , they call this CSP_BITFINS macro. inside this macro all they do is just manipulate bits and fill structures. where do they access that hardware registers to configure ?
If you look further, you'll find that the pointer they are using, gpMCSPIRregs, is volatile and pointing at the memory-mapper hardware registers. The bits they are setting/clearing are in the hardware registers.
I have a VCO with an AD5791 and LPC1768. I am able to read and write to the DAC register of the AD5791 but unable to modify the output frequency or voltage. When the AD5791 is directly connected to a power supply, I can modify the frequency as expected. Therefore I believe this is a software issue. My code is here:
#include "mbed.h"
SPI spi(p5, p6, p7); // mosi, miso, sclk
DigitalOut cs(p8);
DigitalOut LDAC(p9);
DigitalOut Reset(p11);
DigitalOut CLR(p10);
int main()
{
spi.format(8,0);
spi.frequency(10000); // you can speedup later
cs = 1;
Reset = 0;
wait_us(1);
LDAC = 0;
CLR = 1;
Reset = 1; // the chip is reset now
cs = 0;
spi.write(20);
spi.write(0);
spi.write(0);
cs= 1; // this will activate dac
cs = 0;
spi.write(0x14);
spi.write(0xCC);
spi.write(0xCD);
cs = 1; // set output register - shall output some value
do{
}while(1); // wait forever to test the output value
}
Any inputs would be greatly appreciated! Thank you!
The main issue here was that the LPC1768 had to have its software control register and control register set before writing to it. Additionally, the chip had to be driven by LDAC with pauses after data was transferred. This can be seen in my code here: https://gist.github.com/tashwoods/84c81f87fa6e0f1b98a2