Reading and writing fpga registers


#1

Hello Everyone,

I’m trying to read and write the fpga registers using just libusrp
(sorry Eric!).

(1) My write returns “true”, but the read returns 0, regardless of which
fpga register I read/write to (I’ve tried a few). For example:

if (utx->_write_fpga_reg(FR_ADC_OFFSET_0,0x7777)) int readregvalue2 = (utx->_read_fpga_reg(FR_ADC_OFFSET_0));

I must be doing something wrong here.

(2) I believe that the user-defined FPGA registers don’t exist in the
verilog code. Do I need to add them manually? I was going to do that in
usrp_std.v. I’m happy to submit a patch if I get things working where
you can IFDEF the extra registers out if you need the space.

-Roshan


#2

Roshan B. wrote:

(1) My write returns “true”, but the read returns 0, regardless of which
fpga register I read/write to (I’ve tried a few). For example:

if (utx->_write_fpga_reg(FR_ADC_OFFSET_0,0x7777)) int readregvalue2 = (utx->_read_fpga_reg(FR_ADC_OFFSET_0));

I must be doing something wrong here.

The FPGA registers are write-only. When reading, instead of the
register contents, you get ‘readback’ register contents which are
actually a number of useful signals inside the FPGA. See line numbers
304 and 305 of usrp_std.v to see what signals are read back.

The typical way of dealing with write-only registers is to maintain a
shadow copy in your code that you update every time you write to a
register, then if you later want to “read” the register, just look at
the shadow copy. You can also use this if you want to do a
read-modify-write.

(2) I believe that the user-defined FPGA registers don’t exist in the
verilog code. Do I need to add them manually? I was going to do that in
usrp_std.v. I’m happy to submit a patch if I get things working where
you can IFDEF the extra registers out if you need the space.

Correct. The actual registers are not instantiated (they would get
pruned out anyway during synthesis if you did.) If you are writing
custom FPGA code, you can instantiate any number of:

setting_reg #(FR_USER_x) user_reg(…);

…in whatever verilog module you create, and just be sure to include:

usrp/firmware/include/fpga_regs_standard.v

The path in the include statement will vary depending on where your
verilog module is in the filesystem. Also, if you are adding setting
registers to existing modules, then the include may already be done for
you.

Finally, the constants FR_USER_0 through FR_USER_15 are available from
C++ by including:

usrp/firmware/include/fpga_regs_standard.h

(again, path may vary.)


Johnathan C.
Corgan Enterprises LLC
http://corganenterprises.com