8000 multi-dimensional signals? · Issue #455 · myhdl/myhdl · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

multi-dimensional signals? #455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
brightening-eyes opened this issue Apr 12, 2025 · 1 comment
Open

multi-dimensional signals? #455

brightening-eyes opened this issue Apr 12, 2025 · 1 comment

Comments

@brightening-eyes
Copy link

hello.
it would be cool if myHDL could support multi-dimensional signals. this helps coding things like matrix multiplication, convolution etc easier.
suppose this architecture that I am going to talk about:

from myhdl import *

size = 16
data_width = 32

@block
def arr(clk, rst):
    # Flattened memory and registers with proper type initialization
	mem = [[Signal(intbv(0)[data_width:]) for _ in range(size)] for _ in range(size)]

	@always(clk.posedge)
	def logic():
		if rst:
			for i in range(size):
				for j in range(size):
					mem[i][j].next = 0

	return logic

when coding the matrix multiplier, one can index the signal by each index. the same is true for reduction on a given dimension of a matrix, doing broadcasting easier, etc.
with this way, one can even implement tensor operations in myHDL and then transform it into verilog/vhdl.

@josyb
Copy link
Contributor
josyb commented Apr 14, 2025

Hi,

I am working on a new converter approach and I - accidentally :) - added initial support for a true multidimensional Array MyHDL object.
The double level LisOfSignals as you propose is too tedious and (IMO quite important) utterly un-beautiful

Usage would be like:

'''
Created on 14 apr. 2025

@author: josy
'''
from myhdl import block, Signal, intbv, Array, always_seq, instances


@block
def kernel(Clk, Reset, D, ValidIn, K, ValidOut):

    H = K.shape[0]  # number of rows
    V = D.shape[0]  # number of columns

    @always_seq(Clk.posedge, reset=Reset)
    def synch():
        ValidOut.next = ValidIn
        if  ValidIn:
            for j in range(1, H):
                K[j].next = K[j - 1]
            for i in range(V):
                K[0][i].next = D[i]

    return instances()


if __name__ == '__main__':
    from myhdl import ResetSignal

    Clk = Signal(bool(0))
    Reset = ResetSignal(0, 1, False)
    D = Array((3,), Signal(intbv(0)[8:]))
    ValidIn = Signal(bool(0))
    # K = Array((3, 3), Signal(intbv(0)[8:]))
    K = Array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], Signal(intbv(0)[8:]))
    ValidOut = Signal(bool(0))

    dfc = kernel(Clk, Reset, D, ValidIn, K, ValidOut)
    dfc.convert(hdl='SystemVerilog')

I kept the functionality simple on purpose.
Note that logic is a SystemVerilog reserved keyword
Reset is a MyHDL ResetSignal; using it in an always_seq decorator will infer the necessary logic to reset (all) used output variables.

Output:

// File: kernel.sv
// Source: C:\myhdlsupport\myhdl\myhdl\test\development\b_e.py
// Generated by MyHDL 0.12.1
// Date: 2025-04-14 10:24:59 UTC


`timescale 1ns/10ps


module kernel (
	input  logic Clk,
	input  logic Reset,
	input  logic [8 - 1:0] D [0:3 - 1],
	input  logic ValidIn,
	output logic [8 - 1:0] K [0:3 - 1][0:3 - 1],
	output logic ValidOut
);


	always_ff @(posedge Clk) begin: synch
		integer j;
		integer i;
		if (Reset == 1) begin
			ValidOut <= 0;
			K <= '{'{1, 2, 3}, '{4, 5, 6}, '{7, 8, 9}};
		end
		else begin
			ValidOut <= ValidIn;
			if (ValidIn) begin
				for (j = 1; j < 3; j = j + 1) begin
					K[j] <= K[(j - 1)];
				end
				for (i = 0; i < 3; i = i + 1) begin
					K[0][i] <= D[i];
				end
			end
		end
	end: synch


endmodule

You can have a peek at my branch: https://github.com/josyb/myhdl/tree/new_converter
It currently only supports conversion to SystemVerilog - unfortunately the Icarus Verilog simulator only supports little of SystemVerilog so the example above will not pass, but the Sigasi linter doesn't complain.

Regards,
Josy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants
0