Giter Site home page Giter Site logo

systemrdl / peakrdl-regblock Goto Github PK

View Code? Open in Web Editor NEW
47.0 15.0 31.0 944 KB

Generate SystemVerilog RTL that implements a register block from compiled SystemRDL input.

Home Page: http://peakrdl-regblock.readthedocs.io

License: GNU General Public License v3.0

Python 58.75% SystemVerilog 40.73% Tcl 0.36% Shell 0.16%
asic csr fpga registers systemrdl systemrdl-compiler systemverilog systemverilog-hdl

peakrdl-regblock's People

Contributors

amykyta3 avatar apstrike avatar hughjackson avatar jeremiah avatar mkahane avatar motchy869 avatar proukema-fidus avatar risto97 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

peakrdl-regblock's Issues

PeakRDL-regblock AXI-Lite prematurely asserting wready/awready when it can't handle new wdata/awdata

The AXI-Lite code as part of PeakRDL-regblock is unable to handle the case where a new data/address write occurs before a bresp is generated for the previous data-address pair. However the wready/awready signal is asserted and is expecting new writes. This is highlighted in the waveform below where the 2nd wdata is input before the first bresp is generated:
image

As per the AXI-Lite documentation (https://developer.arm.com/documentation/ihi0022/hc?lang=en): "AXI4-Lite supports multiple outstanding transactions, but a Subordinate can restrict this by the appropriate use of the handshake signals" [Section B1.1.4]

Please add enum for register addresses

Hi, I absolutely love this tool you have developed. It does almost anything I have ever wanted in register auto-generation. However, one huge gap is that all of the register addresses in the resulting RTL are hard-coded values rather than being parameters, enums, or defines.

Any chance you would be able to update your design such that the resulting pkg file includes an enum with register addresses at the very least. Or, an additional defines file that does the same would be useful. One thing I've done in the past is produce a file of defines that includes things like LSB, field masks, etc, such that you can use these defines to write testbenches.

This whole thing dovetails nicely with another thing that is missing here, namely autogeneration of C/C++/Python/Rust/etc header files to aid software development.

Thanks for considering!

RCLR of a field at the same cycle as WE next value

I run into this behaviour and I am not sure if it is intended.

If you have a field that is both we and rclr

    field {
        fieldwidth = 8;
        sw = r; hw = wr;
        we;
        rclr;
    } val;

Here you can see I get a we and I am trying to write 0x51 to the register.
But because at the same time rclr arrives, the reset takes priority.

2023-07-28T18:30:29,142613873+02:00

What I expect is that the we will take priority over rclr.
Although this behaviour is probably not specified anywhere, and both can be correct, I think its safer to allow the we first.
If we takes priority there is no risk of losing data, while if rclr takes priority data can be lost.

2023-07-28T18:33:24,123789825+02:00

It comes from this piece of code:

        if(decoded_reg_strb.data && !decoded_req_is_wr) begin // SW clear on read
            next_c = '0;
            load_next_c = '1;
        end else if(hwif_in.data.val.we) begin // HW Write - we
            next_c = hwif_in.data.val.next;
            load_next_c = '1;
        end

To get the second behaviour the if condition needs to be swapped

        if(hwif_in.data.val.we) begin // HW Write - we
            next_c = hwif_in.data.val.next;
            load_next_c = '1;
        end else if(decoded_reg_strb.data && !decoded_req_is_wr) begin // SW clear on read
            next_c = '0;
            load_next_c = '1;
        end

If this is the intended behaviour, maybe a comment in the documentation that rclr takes priority to writing would be helpful.

Verilator support

I done a series of pull requests in Verilator in order to support the code regblock is generating.
In the next release 5.12 I believe most of the things will be supported.
There are still some false linting errors that I still need to fix, but that's not too important.

In order to properly test if everything is supported I need to add a verilator support in your regression tests.

At the moment, I can see that some constructs are falling, like the double hash (##) you use in your testbenches.
I am willing to take a look into issues that can be solved and supported easily.

First to ask you, would you be interested in merging verilator support as a part of your regression tests?
And in case that some construct is not easily fixed in verilator, would you be willing to use an equivalent alternative in order to have verilator support?

Frontend command line application

I believe that this tool could really use a frontend command line application.
Example:

python peakrdl_regblock.py top.rdl submodule1.rdl submodule2.rdl --root=top --output_dir=/path/to/output_dir --cpu_if=APB3_Cpuif

Divide by zero for nested addrmaps

I ran into a divide by zero (% 0 really) when trying to compile a regfile that was defined in multiple files as nested addrmaps. In simplifying the test case I can reduce it to a single simple .rdl file that demonstrates the issue.
Versions: peakrdl-0.8.0 peakrdl-regblock-0.15.0

$ peakrdl regblock test.rdl -o output
Traceback (most recent call last):
  File "/home/ianb/.local/bin/peakrdl", line 8, in <module>
    sys.exit(main())
  File "/home/ianb/.local/lib/python3.8/site-packages/peakrdl/main.py", line 165, in main
    options.subcommand.main(importers, options)
  File "/home/ianb/.local/lib/python3.8/site-packages/peakrdl/subcommand.py", line 154, in main
    self.do_export(top, options)
  File "/home/ianb/.local/lib/python3.8/site-packages/peakrdl_regblock/__peakrdl__.py", line 207, in do_export
    x.export(
  File "/home/ianb/.local/lib/python3.8/site-packages/peakrdl_regblock/exporter.py", line 160, in export
    DesignValidator(self).do_validate()
  File "/home/ianb/.local/lib/python3.8/site-packages/peakrdl_regblock/validate_design.py", line 32, in do_validate
    RDLWalker().walk(self.top_node, self)
  File "/home/ianb/.local/lib/python3.8/site-packages/systemrdl/walker.py", line 150, in walk
    self.current_action = self.do_enter(node, listener)
  File "/home/ianb/.local/lib/python3.8/site-packages/systemrdl/walker.py", line 182, in do_enter
    new_action = listener.enter_AddressableComponent(node) or WalkerAction.Continue
  File "/home/ianb/.local/lib/python3.8/site-packages/peakrdl_regblock/validate_design.py", line 73, in enter_AddressableComponent
    if (node.raw_address_offset % alignment) != 0:
ZeroDivisionError: integer division or modulo by zero

This .rdl fails:

addrmap test {
    addrmap {
       reg {name="Reg A";
            field {
                  sw=rw;
                  hw=r;
                  name="";
                  desc="";
            } A[31:0] = 0x0;
        } A_reg @ 0x0;
        reg {name="Reg B";
            field {
                  sw=rw;
                  hw=r;
                  name="";
                  desc="";
            } B [31:0] = 0x0;
        } B_reg @ 0x4;
    } mapA @ 0x1000;
};

But this .rdl works:

addrmap test {
    reg {name="Reg C";
            field {
                  sw=rw;
                  hw=r;
                  name="";
                  desc="";
            } C[31:0] = 0x0;
        } C_reg @ 0x0;
    addrmap {
       reg {name="Reg A";
            field {
                  sw=rw;
                  hw=r;
                  name="";
                  desc="";
            } A[31:0] = 0x0;
        } A_reg @ 0x0;
        reg {name="Reg B";
            field {
                  sw=rw;
                  hw=r;
                  name="";
                  desc="";
            } B [31:0] = 0x0;
        } B_reg @ 0x4;
    } mapA @ 0x1000;
};

common trigger for array of write-buffered registers

Hi team,
Let's say I have a regfile like this:

regfile my_file #(int unsigned ARRAY_SIZE = 8) {
  default accesswidth = 32;
  default regwidth = 32;

  reg {
    field {sw =rw; hw=r} trigger_bit;
  } write_trigger;

  reg {
    regwidth = 64;
    field{ sw=rw; hw=r} wide_field[63:0];
    buffer_writes=true;
  } buffered_regs[ARRAY_SIZE];

};

My question is this:

1.) how can I concisely apply the write_trigger to all the buffered regs? The example here seems to indicate that all triggers need to be set individually

something like

buffered_regs[*] -> wbuffer_trigger = write_trigger.trigger_bit;

Vivado Simulator Issue

This is almost certainly an issue with XIlinx, but I wanted to point out that I am seeing a Vivado Simulator Failure when running a simulation with a generated register block:

FATAL_ERROR: Vivado Simulator kernel has discovered an exceptional condition from which it cannot recover. Process will terminate. For technical support on this issue, please open a WebCase with this project attached at http://www.xilinx.com/support.
Time: 0 ps Iteration: 0

It does give the line of RTL where it fails in the comb block where s_axil.RDATA is assgined:

https://github.com/SystemRDL/PeakRDL-regblock/blob/main/src/peakrdl/regblock/cpuif/axi4lite/axi4lite_tmpl.sv#L208

which generates the line:

s_axil.RDATA = axil_resp_buffer[axil_resp_rptr[1:0]].rdata;

I was able to hide the error by making the axil_resp_buffer a power of 2 depth, but the waveform didn't indicate any other issues.

Feature Request: Option to remove buffer stage from AXI read/write

Hello PeakRDL Development Team,

I and my project team noticed that there is an additional buffer stage added to the read/write transactions of the AXI Bus. Would it be possible if you add an exporter option to remove the buffer stage, so the read/writes would take one less cycle?

Thank you very much!

regblock compile with no package import

the port list of the reg block module will look something like this:

module my_reg_block (
    input wire clk,
    input wire rst,

    axi4lite_intf.slave s_axil,

    input my_reg_block_pkg::my_reg_block__in_t hwif_in,
    output my_reg_block_pkg::my_reg_block__out_t hwif_out
);

But don't we need a package import like this?

module my_reg_block
import my_reg_block_pkg::*;
(
    input wire
    ...

External memory connections

Hi, I am just looking at your tool for integrating into the workflow at my company. It looks really good!

One thing that is currently a blocker to using this is the lack of support for external memory connections for the purpose of mapping block RAM to an address map. It looks like you were looking into it in issue #4. Are there any plans to role support soon?

I see @ycyang0508 may have been working on this on a fork ycyang0508@358a098 through to ycyang0508@381724e

Thanks

David

peakrdl_regblock\exporter.py does not create output directory before trying to write .sv files

The following command

peakrdl regblock .\mytestmap.rdl -o mytestmap

returns this error on a clean directory:

File "C:\dev\hwtools\head\objects\venv\lib\site-packages\peakrdl_regblock\exporter.py", line 215, in export
stream.dump(package_file_path)
File "C:\dev\hwtools\head\objects\venv\lib\site-packages\jinja2\environment.py", line 1609, in dump
fp = open(fp, "wb")
FileNotFoundError: [Errno 2] No such file or directory: 'mytestmap\TopAddrMap_pkg.sv'

The call to stream.dump(package_file_path) fails if the output_dir folder does not exist.

I added

        if not os.path.isdir(output_dir):
            os.makedirs(output_dir)

just above the call to stream.dump(package_file_path) and was able to successfully write the .sv files. I realize that may not be the correct location to add the code, but it did resolve this issue for me.

fatal: Incompatible assignment to property 'hwenable'

Greetings.

Searching for this error led me to this:

SystemRDL/systemrdl-compiler#31

So this error is fixed in systemrdl-compiler, but not in PeakRDL-regblock?

Additionally, I tried to test only systemrdl-compiler as below:

./print_hierarchy.py <my_rdl>
It still gave same error.

RDL snippet:

field status_field {
   sw = rw; 
   hw = w;
   we; 
   hwenable;
   woclr;
};

It's a fresh installation, so I have all latest.

python3 -m pip install peakrdl-regblock 
Collecting peakrdl-regblock
  Using cached peakrdl_regblock-0.15.0-py3-none-any.whl
Collecting systemrdl-compiler>=1.25.1
  Downloading systemrdl_compiler-1.26.0-cp39-cp39-macosx_10_13_x86_64.whl (1.2 MB)

Add option to generate a "hwif report"

Navigating the hwif struct could be a little cumbersome if you don't know what you're
looking for.

A text report of the structure might be useful to users:

hwif_out.foo[0:3].bar.value
hwif_out.foo[0:3].baz.value

swmod early?

Using peakrdl-regblock 0.14.0 and I am trying to generate a register that will signal to the hardware when a new value is written. I believe the swmod property is the best way to go, but I am finding I would have to add an additional flop to use the swmod signal. It is not clear to me in the SystemRDL 2.0 spec when swmod should be asserted, but I believe it would be more useful if it were 1 cycle later.

Thank you,
Zach

Add feature to generate _pkg with no cpuif / generate cpuif with no _pkg

In the case of module level testing or isolated module development, it would be useful to only generate the _pkg.sv

In the case of reusing modules whose wire I/F are passed through the hierarchy, when the module to control the wire I/F is generated it is necessary to generate the cpuif, but we don't want to regenerate the _pkg.sv

Please see this development flow example:

Module_A (a reusable block with control and status registers)

files:

  • module_a_pkg.sv
  • module_a.sv
module module_a
(
module_a_in   reg_in,
module_a_out reg_out,
);
endmodule

Module_B

files:

  • module_b.sv
  • module_a_reg.sv
module module_b
();
module_a_in a_reg_in;
module_a_out a_reg_out;

module_a_reg (
  .cpuif(cpuif),
  .a_reg_in(a_reg_in),
  .a_reg_out(a_reg_out)
)
module_a a (
  .a_reg_in(a_reg_in),
  .a_reg_out(a_reg_out)
);
endmodule

You can see that the _pkg.sv is the exported wire I/F to the module in this case, where some higher level module will then convert the wire IF to a bus I/F

By bisecting the generation it allows for module reuse in this particular use case.

Use scalar if conditions

Hello Alex,

May you make the conditions for if statements scalars instead of vectors (see image below)? This has been causing Spyglass Lint to generate warning messages. Thank you!

image

Removing "if(1)" Conditions

Hello Alex,

I noticed that for single pulse registers, PeakRDL-regblock is generating if(1) conditions for resetting the registers back to 0, such as in the code below.

            ....
            load_next_c = '1;
        end else if(1) begin // singlepulse clears back to 0
            next_c = '0;
            load_next_c = '1;
        end

May I request that the if(1) conditions be omitted for singlepulse registers (and other components/registers), because it generates warning messages and has the possibility to cause synthesizers to generate extra logic?

Thank you!

Use literals of the same size in comparisons

Hello Alex,

May you please use literals of the same size in comparisons (see image below)? This has been causing Spyglass Lint to generate warning messages. Thank you very much!

image

Is external memory/register supported ?

Hi,
Is external memory/register supported ?

I have tried the following:
external my_reg ext_my_reg ;

But the tool report error:
error: Exporter does not support external components

Best Regards
Derek Wang

Instantiation stub to use generated RTL

It would be very helpful to have an option in the tool to generate an instantiation stub that can be used within the design using the register map code to instantiate it. This would be beneficial especially for RDL files that have a lot of fields and would avoid having to write down each field name manually and would also reduce the chance of human error in instantiating the register map code.

This feature was added to our local copy of the PeakRDL code as a new class within the generators.py file in the hardware interface (hwif) directory.

setup.py is not installing subpackages

Hi,

the setup.py is not installing the subpackages (cpuif, field_logic, hwif ...). Changing the hardcoded packages statement in setup.py as follows, includes all subpackages under peakrdl:
packages=setuptools.find_namespace_packages(include=["peakrdl*"]) ,

regards
Philip

Add an option for non structured hwif/cpuif

As our flow prefer the hardware interface without structure-like interface, do we have possibility to add such an option to generate the hardware interface with every signal declared explicitly?

Add an identifier filter

It is super annoying when your RDL file uses an identifier that happens to be a SystemVerilog keyword and results in a compile error.

It would be better if the tool would simply sanitize this.
Implement an identifier filter function that EVERYTHING gets passed through.
If any token collides with a SV keyword, augment it somehow.

Do something like append/prepend "_" to the name? Or some other prefixing/suffixing scheme...
Either way, the filter function should be something users can override to their liking

Making bit widths of vectors the same when doing comparisons

Hello PeakRDL Development Team,

Is it possible that, in the future versions, the bit widths of vectors be set to the same in comparisons? For example, cpuif_req_masked & (cpuif_addr == 'h0) can become cpuif_req_masked & (cpuif_addr == 8'h0) when the address width is 8. I know there are other parts of the script that generate these comparisons, and I wish these can be improved as well.

I and my team are currently seeing many warning messages about bit widths of vectors not matching during our simulations, and thus we kindly wish the improvement can be made. We appreciate your consideration.

Thank you very much!

Sample code license

Hi,

Is the sample code in your documentation licensed? It would be good if it were explicitly licensed so people would know what rights and obligations they have should they choose to reuse the sample code.

Thanks

Add support for double-buffered reads and writes

Introduction

The SystemRDL spec does not formally define a mechanism to describe double-buffered register accesses.

When a register's accesswidth < regwidth, it is not possible to access the entire register atomically. One must perform multiple sw operations to do so. This can be problematic when the contents of a register require atomic access - for example a rapidly incrementing counter that spans multiple sub-words cannot be reliably read without risking reading an invalid value.
Other situations may demand the ability to read or update numerous adjacent registers atomically.

Proposal

Add functionality to the regblock exporter to understand the following user defined properties (UDPs) that can be applied to reg components:

  • buffer_writes
    • If set, writes to this register are double-buffered. Writes to the register's address are buffered and are only committed to the register once the appropriate trigger is activated.
  • wbuffer_trigger
    • Optional reference to a reg instance, or single-bit signal or field that triggers the buffer to be applied to the register.
    • If unspecified, sw writes to the highest address of the register will trigger the buffer commit action.
  • buffer_reads
    • If set, this register's read value is latched and held so that it can be read atomically
  • rbuffer_trigger
    • Similar to wbuffer_trigger, this defines the trigger event for latching a value into the register's read buffer.
    • If unspecified, sw reads to the lowest address of the register will trigger the buffer latch action.

Buffered write, trigger is a field of the register

If a field is a trigger for the register like this:

property buffer_writes {
    component = reg;
    type = boolean;
};

property wbuffer_trigger {
    component = reg;
    type = ref;
};

addrmap testmap {
    reg {
        regwidth = 32;
        field { fieldwidth = 1; sw = w; hw=r;} commit = 0;
        field { fieldwidth = 8; sw = w; hw=r;} some_field = 0;
        buffer_writes = true;
        wbuffer_trigger = commit;
    } some_reg;
};

The problem is in order for commit to update the value of commit in field_storage needs to change, but it will only change once it is commited, right?
So I think it should have this change:

    always_comb begin
        automatic logic [0:0] next_c = field_storage.some_reg.commit.value;
        automatic logic load_next_c = '0;
-        if(wbuf_storage.some_reg.pending && field_storage.some_reg.commit.value) begin // SW write
+        if(wbuf_storage.some_reg.pending && wbuf_storage.some_reg.data[0:0]) begin // SW write
            next_c = (field_storage.some_reg.commit.value & ~wbuf_storage.some_reg.biten[0:0]) | (wbuf_storage.some_reg.data[0:0] & wbuf_storage.some_reg.biten[0:0]);
            load_next_c = '1;
        end
        field_combo.some_reg.commit.next = next_c;
        field_combo.some_reg.commit.load_next = load_next_c;
    end

I think its fine to have trigger in the same register, as it would be possible to strobe (#38) parts of the data and then on strobing the part where commit is located, the data should be commited.

If you point me where I should look for the fix, I can do it also.

Address line width off-by-one

Hello PeakRDL Development Team,

It seems that for an address map with size 128 bytes, the Verilog module generated by PeakRDL will have an address line that is 8 bits wide. However, in reality, only 7 bits are required for the address line because the address range only goes from 0 to 127.

I checked your source code and saw the line self.addr_width = self.top_node.size.bit_length() under class DesignState and request that it be changed to self.addr_width = (self.top_node.size - 1).bit_length().

Thank you!

Add better hooks for user extensions

Currently it is impossible/impractical for users to extend the register generator beyond the limited extensions I allow in the CPUIF layer.
Add provisions to allow people to inject their own custom extensions.
Specifically:

  • Augment/override field logic behavior
  • Extend field logic behavior with their own user defined properties

Integer literals should be sized to avoid 32-bit truncation

Hi team, I have noticed that when the field storage reset value is rendered, the reset value is rendered without a width:

i.e. if I have the following register:

        reg {
            field {
                hw = na; sw = rw;
            } pad[63:0] = 64'h12345678abcdef13;
        } scratch_pad;

then the reset value will be rendered as:

field_storage.registers.scratch_pad.pad.value <= 'h12345678abcdef13;

When synthesizing or simulating on machines with 32-bit integers, this will truncate down to 32-bits

I'd like to propose a patch like this one to allow for full width reset values of arbitrary size:

--- a/src/peakrdl_regblock/field_logic/generators.py
+++ b/src/peakrdl_regblock/field_logic/generators.py
@@ -220,7 +220,7 @@ class FieldLogicGenerator(RDLForLoopGenerator):
 
         reset_value = node.get_property('reset')
         if reset_value is not None:
-            reset_value_str = self.exp.dereferencer.get_value(reset_value)
+            reset_value_str = str(node.width) + self.exp.dereferencer.get_value(reset_value)
         else:
             # 5.9.1-g: If no reset value given, the field is not reset, even if it has a resetsignal.
             reset_value_str = None

Add support for external

As is mentioned in the known limitations, PeakRDL-regblock has no support for external registers or regfile. Having support for external is necessary for certain common use cases:

  • FIFO read access
  • Mapping to block RAM read
  • Any other read that must be qualified with a 'read enable' and has arbitrary latency

My suggestion is that the 'out' struct get a scoped 'read enable' signal for any external read. The 'in' struct will contain a 'valid' signal indicating the read is complete and the 'in' data is to be forwarded back to the axi/ahb/cpu bus

swacc should be asserted on read and write

The SystemRDL databook says:

swacc indicates a generated output signal shall notify hardware when this field is accessed by software.

The way I interpret the word "access" is a read or write. But it seems like PeakRDL interprets it as only a read. This is the relevant RTL that I see being generated:

assign hwif_out.my_reg.my_field.swacc = decoded_reg_strb.my_reg && !decoded_req_is_wr;

I believe the generator should be changed to remove the && !decoded_req_is_wr from the RHS of this assignment.

Add option to generate a UVM HDL Path overlay

UVM users will want to be able to access fields via backdoor paths.
This is something that ought to be automated.

Add an option to generate an additional SV package or include that contains a class definition:

class my_block_uvm_utils_t #(type T = uvm_reg_block);
    function apply_hdl_paths(T block, path_prefix="");
        ...
    endfunction
endclass

This would allow one to use the utility class/function to apply HDL paths to UVM register model nodes that correspond to the auto-generated regblock. It would be up to the user to complete the HDL path prefix string to the regblock as appropriate:

typedef my_block_uvm_utils_t #(my_block_uvm_reg_block) my_block_utils;
my_block_utils::apply_hdl_paths(my_model.path.to.inst_a, "path.to.a")
my_block_utils::apply_hdl_paths(my_model.path.to.inst_b, "path.to.b")

...which would automatically populate the UVM backdoor paths using the register model API

Parity Implementation (with preferably per-register storage, not per-field)

A feature which is a must for us (functional safety) is to protect the contents of the register file/storage with parity... I see that currently it is not supported (adding 'paritycheck;'

In addition, for efficiency (less storage) it would be great to implement only 1 parity bit per register (and not 1 bit per field).
whenever any of the register fields (that have parity) change, either from the HW (hw=w) or SW side, parity should be re-calculated.

swmod latency

Currently the swmod signal on a register is asserted before the update output data is available. This requires it be delayed externally by one lock in order to use it as a write enable to a FIFO/RAM/etc. It would seem to make more sense to delay it one clock so it aligned with the value update. Is the current behavior required by the SystemRDL spec or implementation defined? Obviously there may be some issue with updating it now, as it would be a (silent) breaking change. It could be an option, but that seems excessive?

One potential downside would be that swacc and swmod could be triggered in different clock cycles for the same access.

image

Emit Parametrized PeakRDL output

Greetings !
Awesome project BTW!

I did a quick pilot in my company using PeakRDL with Synopsys VCS, replacing an existing register module with SystemRDL specification + PeakRDL output. Worked Nicely.

A feature that we miss is the ability to emit parametrized output. Meaning keep the symbolic SystemRDL parameters in the generated RTL instead of replacing them with actual values.

This can allow us to embed the generated RTL CSR module in a generic/parametrized design, have the user specify actual parameters in the instantiation, and let those Parameter values seep down to the generated CSR RTL. (in addition to configuring the logic that surrounds the register module).

This can be a killer feature..
Is this a change that can be done at the PeakRDL generator level? or is this in the SystemRDL Parser code/project before that?

Any help appreciated,
I think I'll take a look myself..

Thanks in advance, Gal.

Address with appears to max out at 24 bits

Hi Alex, hope things are going well.
I'm hoping to move to using systemrdl for my register definitions. I am running into a problem with the address widths. If I understand correctly, peakrdl- regblock is supposed to extract the necessary address width from the register definition. If I use the following rdl code:

addrmap BOEEye_reg {
    default regwidth=64;
    reg {
        field {
            desc   = "FL2 Value";
            sw     = r;
            hw     = w;
        } num[7:0];
    } fl2 @32'h01C00018;
};

The code generated limits the addresses to 25 bits. The problem is that this may cause overlaps with other generated blocks if I am using the whole 32 bit address space. For example, 1C00018 would also decode register accesses to 3C00018 since it is ignoring bit [31:25] being a 0. Is there a way to specify the address width to get around this?

Sorry if this is a stupid question, I'm just starting to explore this.
Thanks,
Frank

VHDL exporter

Hi, first of all thanks for the great work in all SystemRDL/PeakRDL projects. It's really impressive what has been accomplished here 👍
I'm currently looking into some automation tools to use for AXI slave generation from SystemRDL we currently extensively use in the company I work for. For some projects, we are required to write in VHDL, so the current SV exporter (although pretty darn nice by itself) doesn't really meet our needs. I have found https://github.com/MicroTCA-Tech-Lab/hectare project which looks sufficient for now, yet limited and seems to be abandoned over the last year. So here comes my question, whether there is a VHDL exporter in the pipeline for this project, or only SV variant development is planned?

Thanks again for the great work.

Add support for write broadcasting

A common design pattern is to implement an address region that broadcasts write operations to multiple registers. This saves on software cycles since a single SW write can be used to broadcast a configuration to multiple registers simultaneously.

Since this is not supported by SystemRDL's built-in properties, add this as a UDP extension.

For example:

my_reg_t rega;
my_reg_t regb;
my_reg_t regc[4];

my_reg_t reg_all;

reg_all -> broadcast_write = '{
    rega, regb, regc
};

Writing to reg_all is equivalent to individually writing to rega, regb, and all of regc

Semantics:

  • The broadcast_write property is valid on reg or regfile components
  • If a component is assigned broadcast_write, its hw implementation is omitted. Instead, all the broadcast targets the property references inherit an additional SW write-enable strobe.
  • broadcast_write accepts an array of one or more references.
  • Each reference shall be the exact same component type and datatype as the assignee
  • A reference to a regfile applies recursively to all its child registers
  • A reference to an entire array applies to all elements in the array
  • A reference to a specific array element is not supported
  • A broadcaster and its targets shall be internal to each other. (one cannot be external compared to the other)
  • A software read operation on the broadcaster is illegal and the implementation may optionally return a cpuif error.

How to create CSR's software access property controlled by hardware ?

Hi,
How to create a register which SW read and write access property is controlled by hardware ?
I know that "swwe" and "swwel" is used to control the write access property. But how about read access property ?

  My intentiion is to create a register which could only be accessed by SW when another register is not set.

Best Regards
Derek Wang

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.