SystemRDL / systemrdl-compiler

SystemRDL 2.0 language compiler front-end
http://systemrdl-compiler.readthedocs.io
MIT License
236 stars 69 forks source link

accesswidth/regwidth limitations #98

Closed jeras closed 3 years ago

jeras commented 3 years ago

SystemRDL-compiler is missing a check, standard section 10.6.1 Semantics, point c). "The value of the accesswidth property shall not exceed the value of the regwidth property." In my case access width was specified as a default of 64 and register width was 32, The tool did not report an error.

I initially misunderstood what is the purpose of accesswidth, and I thought it is the width of the data bus in RTL code.

It actually "Specifies the minimum software access width (power of two) operation that may be performed on the register.". I tried to make a parallel with my experience, to be able to give a sensible example.

A 32-bit register with byte access would have: accesswidth = 8 regwidth = 32 This is common for memories, but registers usually do not have byte access. accesswidth = 32 regwidth = 32

I still have 2 questions remaining (I am asking since I noticed your errata for the standard, so I see you as an expert):

  1. What would be the best way to describe/decide the bus address width? Is it one of the parameters, or should it be defined with a custom approach?
  2. If I define a register with a width larger then 64-bit, for example 128 bits (quad precision floating point), how would I specify the reset value, since the data type used to specify reset values is only 64bit (longint unsigned). Even if regwidth is limited to 64-bit, would it be possible to have signalwidth=128 and somehow specify the concatenation of multiple registers into the signal?
amykyta3 commented 3 years ago

I was actually looking into the same thing recently!

I agree that the check described in 10.6.1-c is missing. I had initially waived it in the errata, but after looking at this in more detail, I no longer agree with my rationale. I plan to enforce 10.6.1-c in the next release.

I initially misunderstood what is the purpose of accesswidth, and I thought it is the width of the data bus in RTL code. It actually "Specifies the minimum software access width (power of two) operation that may be performed on the register.".

I agree this is a little strange. I had never noticed until your emphasis on "minimum". I think this is another example where poor phrasing in the RDL spec is causing confusion, and we're simply taking it too literally. This is a common issue I have noticed in other sections too. Regardless of the phrasing of that clause, I believe accesswidth does indeed imply the bus width. The spec does not give too many examples, but it sure seems to imply it has something to do with the bus width in 10.6.1-f:

Any field that is software-writable or clear on read shall not span multiple software accessible sub-words (e.g., a 64-bit register with a 32-bit access width may not have a writable field with bits in both the upper and lower half of the register).

This presents an example where a hardware limitation prevents access to all 64-bits simultaneously. The use of "sub-words" implies this is referring to a hardware bus width (see https://en.wikipedia.org/wiki/Word_(computer_architecture))

Perhaps when they used the word "minimum", the spec authors were referring to register protocols like AXI4 or AHB where a transaction can perform a burst access. In the context of a burst protocol, the minimum access width would be identical to the bus width. Even so, this phrasing is a little imprecise. Some protocols allow for write byte strobes which allow one to modify individual bytes, but I do not think this applies since it doesn't change the actual transaction's access width (strobes are meaningless for read transactions).

So to respond to your question:

What would be the best way to describe/decide the bus address width? Is it one of the parameters, or should it be defined with a custom approach?

I think accesswidth is still the correct property to use to infer the hardware bus width. It seems strange to me that this is a property of a reg component. It would have been more appropriate to be a property of addrmap. It would not make much sense if a register block had varying accesswidth.

If I define a register with a width larger then 64-bit, for example 128 bits (quad precision floating point), how would I specify the reset value, since the data type used to specify reset values is only 64bit (longint unsigned). Even if regwidth is limited to 64-bit, would it be possible to have signalwidth=128 and somehow specify the concatenation of multiple registers into the signal?

If you look at 9.5, Table 13, you'll see that the reset property is of type bit. The bit type is similar to Verilog's where it can contain large bit vector values. Specifying a large reset value will work fine:

reg my_reg {
    regwidth = 128;
    field {
        sw=rw; hw=r;
    } my_field[127:0] = 0x01234567_89abcdef_aaaabbbb_ccccdddd;
    // Or use verilog notation: 128'h01234567_89abcdef_aaaabbbb_ccccdddd
}
jeras commented 3 years ago

I will first write about the bit type, which the standard seems to use it as a vector, without explicitly saying bit vector. As long as the SystemRDL-compiler can handle numbers larger then 64-bit, I can ignore the standard being vague about it.

Regarding accesswidth I found two short sections in the AMBA AXI5 standard discussing the relation between the full and lite standard that seem close to the accesswidth issue, this are sections B1.1.2 and B1.1.3.

I actually think accesswidth should be redefined to be more about byte access, and a custom parameter applied to addrmap should be used for bus datawidth. I do not think any mental gymnastics would shape this part of the standard into something sensible.