There will a few different opinions on your question.
IMHO you are swapping the cart and the horse. Obviously you know Verilog quite well (I don’t …) and you are asking whether there is an equivalent way to write this in MyHDL. The idea behind MyHDL is that we write standard Python to simulate (first) and convert (second) to an intermediate representation, at the time VHDL or Verilog.
The question becomes: do we have a Python construct that later in conversion can come out in the desired format(s)?
The way I would (currently do) write this:
from myhdl import Signal, intbv, block, always_comb
@block
def vwe(svalid, en, dready, sready, dvalid):
@always_comb
def assign():
for i in range(len(en)):
dvalid.next[i] = svalid and en[i]
sready.next = 1 if (dready & en) else 0
return assign
if __name__ == '__main__':
def convert():
en, dready, dvalid = [Signal(intbv(0)[4:]) for _ in range(3)]
sready, svalid = [Signal(bool(0)) for _ in range(2)]
dfc = vwe(svalid, en, dready, sready, dvalid)
dfc.convert(hdl='Verilog')
dfc.convert(hdl='VHDL')
convert()
produces this Verilog:
// File: vwe.v
// Generated by MyHDL 0.10
// Date: Sat Oct 6 11:50:18 2018
`timescale 1ns/10ps
module vwe (
svalid,
en,
dready,
sready,
dvalid
);
input svalid;
input [3:0] en;
input [3:0] dready;
output sready;
reg sready;
output [3:0] dvalid;
reg [3:0] dvalid;
always @(en, svalid, dready) begin: VWE_ASSIGN
integer i;
for (i=0; i<4; i=i+1) begin
dvalid[i] = (svalid && en[i]);
end
sready = (dready & en) ? 1 : 0;
end
endmodule
Which will work fine, but alas doesn’t have the conciseness of the Verilog code you presented.
Ideally you want to write something like:
@block
def vwe(svalid, en, dready, sready, dvalid):
@always_comb
def assign():
dvalid.next[i] = bitextend(svalid, NUM_W) and en[i]
sready.next = 1 if (dready & en) else 0
return assign
Assuming we have the function bitextend defined (as a built-in?) to do what it needs to do, this code will simulate fine. It does convert fine too, but instead of the targeted Verilog construct it will include a function.
function [4-1:0] MYHDL2_bitextend;
input [1-1:0] b;
input w;
integer w;
reg [4-1:0] r;
integer i;
begin: MYHDL5_RETURN
r = 4'h0;
for (i=0; i<w; i=i+1) begin
r[i] = b;
end
MYHDL2_bitextend = r;
disable MYHDL5_RETURN;
end
endfunction
assign dvalid = (MYHDL2_bitextend(svalid, 4) & en);
assign sready = (dready & en) ? 1 : 0;
endmodule
Now we could make the converter(s?) smarter and if we define a number of functions as built-in we could have the converter recognise them and implement the appropriate construct.
But I am sure that there are other priorities to extend MyHDL.
@cfelton, @hgomersall, and others … Your ideas?