major interface conversion update

- module instances with modport bindings are now inlined
- support for modports in generate loops
- support for generic interfaces
- implied modport instance propagation
- add error message for interface instances missing port list
This commit is contained in:
Zachary Snow
2020-08-08 20:43:47 -06:00
parent 5161a9e71b
commit 67466eaa60
23 changed files with 809 additions and 492 deletions
+3 -6
View File
@@ -1,18 +1,16 @@
interface bundle;
logic [1:0] index;
logic clock;
logic [3:0] inp;
logic [1:0] index = 0;
logic clock = 0;
logic [3:0] inp = '1;
logic out;
endinterface
module rotator(bundle b);
initial b.index = 0;
always @(posedge b.clock)
b.index <= b.index + 1;
endmodule
module setter(bundle b);
initial b.inp = '1;
always @(posedge b.clock)
b.inp[b.index] <= b.out;
endmodule
@@ -23,7 +21,6 @@ endmodule
module clocker(bundle b);
initial begin
b.clock <= 0;
forever
#5 b.clock <= ~b.clock;
end
+8 -14
View File
@@ -1,8 +1,8 @@
module impl(b_index, b_clock, b_inp, b_out);
output reg [1:0] b_index;
output reg b_clock;
output reg [3:0] b_inp;
output wire b_out;
module impl;
reg [1:0] b_index;
reg b_clock;
reg [3:0] b_inp;
wire b_out;
initial b_index = 0;
always @(posedge b_clock)
@@ -19,15 +19,6 @@ module impl(b_index, b_clock, b_inp, b_out);
forever
#5 b_clock <= ~b_clock;
end
endmodule
module top;
wire [1:0] b_index;
wire b_clock;
wire [3:0] b_inp;
wire b_out;
impl impl(b_index, b_clock, b_inp, b_out);
initial begin
$monitor("%b %b %b %b", b_index, b_clock, b_inp, b_out);
@@ -36,3 +27,6 @@ module top;
end
endmodule
module top;
impl impl();
endmodule
+53
View File
@@ -0,0 +1,53 @@
interface Interface #(num_clients = 0);
bit [num_clients-1:0] req;
for (genvar i = 0; i < num_clients; ++i) begin : mps
modport client_mp (output .client_req(req[i]));
end
endinterface
module ClientAnd (client_ifc, bits);
parameter WIDTH = 2;
Interface client_ifc;
input [WIDTH-1:0] bits;
assign client_ifc.client_req = &bits;
endmodule
module ClientTick #(start = 0, period = 1) (Interface client_ifc, input clock);
initial client_ifc.client_req = start;
integer counter;
initial counter = 0;
always @(posedge clock) begin
counter += 1;
if (counter % period == 0)
client_ifc.client_req = ~client_ifc.client_req;
end
endmodule
module top;
logic clock;
initial begin
clock = 1;
forever #1 clock = ~clock;
end
parameter N = 8;
Interface #(.num_clients(N)) intf();
for (genvar j = 0; j < N - 1; j++) begin : clients
ClientTick #(j, j + 1) client(
.clock,
.client_ifc(intf.mps[j + 1].client_mp)
);
end
ClientAnd #(4) client(
.bits(intf.req[4:1]),
.client_ifc(intf.mps[0].client_mp)
);
initial begin
$monitor("%0d %b %b", $time, clock, intf.req);
#100 $finish;
end
endmodule
+57
View File
@@ -0,0 +1,57 @@
module ClientAnd (client_req, bits);
parameter WIDTH = 2;
output client_req;
input [WIDTH-1:0] bits;
assign client_req = &bits;
endmodule
module ClientTick #(
parameter start = 0,
parameter period = 1
) (
output reg client_req,
input clock
);
initial client_req = start;
integer counter;
initial counter = 0;
always @(posedge clock) begin
counter += 1;
if (counter % period == 0)
client_req = ~client_req;
end
endmodule
module top;
reg clock;
initial begin
clock = 1;
forever #1 clock = ~clock;
end
parameter N = 8;
generate
begin : intf
wire [N-1:0] req;
end
genvar j;
for (j = 0; j < N - 1; j = j + 1) begin : clients
ClientTick #(j, j + 1) client(
.clock,
.client_req(intf.req[j + 1])
);
end
endgenerate
ClientAnd #(4) client(
.bits(intf.req[4:1]),
.client_req(intf.req[0])
);
initial begin
$monitor("%0d %b %b", $time, clock, intf.req);
#100 $finish;
end
endmodule
+72
View File
@@ -0,0 +1,72 @@
interface InterfaceA;
task hello;
input integer inp;
$display("Hello from InterfaceA %0d", inp);
endtask
logic [20:0] x = 21'b01011_00100000_01011110;
endinterface
interface InterfaceB;
task hello;
input integer inp;
$display("Hello from InterfaceB %0d", inp);
endtask
logic [10:0] x = 11'b011_11110100;
endinterface
// could get bound to any of the interfaces or modports
module Module(interface i);
initial #4 i.hello(1);
initial #5 $display("Module got %b", i.x);
endmodule
interface InterfaceM;
logic [4:0] x = 0;
task hello;
input integer inp;
x = x + 1;
$display("Hello from InterfaceM %0d %b", inp, x);
endtask
modport A(input .x(x[0]));
modport B(input .x(x[2:1]));
endinterface
// could get bound to the entire interface bundle, or either modport
module ModuleM(InterfaceM i);
initial i.hello(-1);
initial $display("ModuleM got %b", i.x);
endmodule
module ModuleWrapperMA(InterfaceM.A i); Module m(i); endmodule
module ModuleWrapperMB(InterfaceM.B i); Module m(i); endmodule
module ModuleWrapperM (InterfaceM i); Module m(i); endmodule
module ModuleMWrapperMA(InterfaceM.A i); ModuleM m(i); endmodule
module ModuleMWrapperMB(InterfaceM.B i); ModuleM m(i); endmodule
module ModuleMWrapperM (InterfaceM i); ModuleM m(i); endmodule
module top;
InterfaceM im();
Module c(im.A);
Module d(im.B);
Module e(im);
ModuleM x(im.A);
ModuleM y(im.B);
ModuleM z(im);
InterfaceA ia();
InterfaceB ib();
Module a(ia);
Module b(ib);
ModuleWrapperMA cw(im);
ModuleWrapperMB dw(im);
ModuleWrapperM ew(im);
ModuleMWrapperMA xw(im);
ModuleMWrapperMB yw(im);
ModuleMWrapperM zw(im);
endmodule
+59
View File
@@ -0,0 +1,59 @@
module impl;
reg [4:0] im_x = 0;
task im_hello;
input integer inp;
begin
im_x = im_x + 1;
$display("Hello from InterfaceM %0d %b", inp, im_x);
end
endtask
initial #4 im_hello(1);
initial #5 $display("Module got %b", im_x[0]);
initial #4 im_hello(1);
initial #5 $display("Module got %b", im_x[2:1]);
initial #4 im_hello(1);
initial #5 $display("Module got %b", im_x);
initial im_hello(-1);
initial $display("ModuleM got %b", im_x[0]);
initial im_hello(-1);
initial $display("ModuleM got %b", im_x[2:1]);
initial im_hello(-1);
initial $display("ModuleM got %b", im_x);
task ia_hello;
input integer inp;
$display("Hello from InterfaceA %0d", inp);
endtask
wire [20:0] ia_x = 21'b01011_00100000_01011110;
task ib_hello;
input integer inp;
$display("Hello from InterfaceB %0d", inp);
endtask
wire [10:0] ib_x = 11'b011_11110100;
initial #4 ia_hello(1);
initial #5 $display("Module got %b", ia_x);
initial #4 ib_hello(1);
initial #5 $display("Module got %b", ib_x);
initial #4 im_hello(1);
initial #5 $display("Module got %b", im_x[0]);
initial #4 im_hello(1);
initial #5 $display("Module got %b", im_x[2:1]);
initial #4 im_hello(1);
initial #5 $display("Module got %b", im_x);
initial im_hello(-1);
initial $display("ModuleM got %b", im_x[0]);
initial im_hello(-1);
initial $display("ModuleM got %b", im_x[2:1]);
initial im_hello(-1);
initial $display("ModuleM got %b", im_x);
endmodule
module top;
impl impl();
endmodule
+14 -11
View File
@@ -1,18 +1,21 @@
module Module(input wire x);
initial $display("Module %d", x);
endmodule
module top;
wire i_x = 0;
genvar g;
localparam SOME_VAL = 3;
initial $display("Interface %d %d", i_x, SOME_VAL);
Module m(.x(i_x));
generate
genvar g;
for (g = 10; g < 15; g = g + 1) begin
initial $display(g);
begin : i
wire x = 0;
initial $display("Interface %d %d", x, SOME_VAL);
for (g = 10; g < 15; g = g + 1) begin
initial $display(g);
end
end
for (g = 0; g < 5; g = g + 1) begin
initial $display(g);
endgenerate
generate
begin : m
initial $display("Module %d", i.x);
for (g = 0; g < 5; g = g + 1) begin
initial $display(g);
end
end
endgenerate
endmodule
+6 -3
View File
@@ -20,8 +20,8 @@ module ModuleA(Interface.ModportA m);
endmodule
module ModuleB(Interface.ModportB m);
parameter WIDTH = 0;
initial m.x = 1;
localparam WIDTH = 2 * m.WIDTH;
always @(posedge m.clock) begin
logic temp;
temp = m.x[WIDTH-1];
@@ -33,7 +33,10 @@ module ModuleB(Interface.ModportB m);
endmodule
module ModuleBWrapper(Interface.ModportB m);
ModuleB b(m);
parameter WIDTH = 0;
ModuleB #(WIDTH) b(m);
integer i = 0;
initial #1 $display("shadow i = %d, %b", i, m.x);
endmodule
module ModuleAWrapper(Interface.ModportA m);
@@ -45,7 +48,7 @@ module Tester(input clock);
logic [WIDTH-1:0] idx1, idx2;
Interface #(2 ** WIDTH) i(clock, '{idx1, idx2});
ModuleAWrapper a(i);
ModuleBWrapper b(i);
ModuleBWrapper #(2 * 2 ** WIDTH) b(i);
always @(negedge clock)
$display("%d %0d %2d %2d %b", $time, WIDTH, idx1, idx2, i.x);
endmodule
+3
View File
@@ -10,6 +10,9 @@ module Tester(input clock);
assign idx1 = $clog2(x[2*DATA_WIDTH-1:DATA_WIDTH]);
assign idx2 = $clog2(x[DATA_WIDTH-1:0]);
integer i = 0;
initial #1 $display("shadow i = %d, %b", i, x);
always @(posedge clock) begin : block
localparam SIZE = 2 * DATA_WIDTH;
integer i;
+32
View File
@@ -0,0 +1,32 @@
interface InterfaceA;
logic x;
modport M(input x);
endinterface
interface InterfaceB;
logic y;
modport N(input y);
endinterface
module ModuleA(modport_a);
InterfaceA modport_a;
initial $display("ModuleA %b", modport_a.x);
endmodule
module ModuleB(modport_b);
InterfaceB modport_b;
InterfaceA interface_a();
ModuleA module_a(interface_a.M);
initial $display("ModuleB %b", modport_b.y);
assign interface_a.x = 0;
endmodule
module ModuleC;
InterfaceB interface_b();
ModuleB module_b(interface_b.N);
assign interface_b.y = 1;
endmodule
module top;
ModuleC module_c();
endmodule
+12
View File
@@ -0,0 +1,12 @@
module ModuleC;
wire y;
assign y = 1;
initial $display("ModuleB %b", y);
wire x;
assign x = 0;
initial $display("ModuleA %b", x);
endmodule
module top;
ModuleC module_c();
endmodule
+21 -11
View File
@@ -1,13 +1,23 @@
module top;
wire x, f_x;
wire f_a_x, f_b_x;
assign x = 1;
assign f_x = x;
assign f_a_x = x;
assign f_b_x = ~x;
initial begin
$display("bar got %b", f_a_x);
$display("bar got %b", f_b_x);
end
wire x = 1;
generate
begin : f
wire x;
begin : a
wire x;
initial begin
$display("bar got %b", x);
end
end
assign a.x = x;
begin : b
wire x;
initial begin
$display("bar got %b", x);
end
end
assign b.x = ~x;
end
assign f.x = x;
endgenerate
endmodule
+12 -6
View File
@@ -12,10 +12,16 @@ module M(data);
endmodule
module top;
wire [31:0] x_data = 0;
wire [9:0] y_data = 0;
M #(.WIDTH(32)) a(x_data);
M #(.WIDTH(10)) b(y_data);
M #(3, 32, 4) c(x_data);
M #(5, 10, 6) d(y_data);
generate
begin : x
wire [31:0] data = 0;
end
begin : y
wire [9:0] data = 0;
end
endgenerate
M #(.WIDTH(32)) a(x.data);
M #(.WIDTH(10)) b(y.data);
M #(3, 32, 4) c(x.data);
M #(5, 10, 6) d(y.data);
endmodule
+32
View File
@@ -0,0 +1,32 @@
typedef struct packed { logic x; } T;
interface Interface;
integer x;
function z;
input x;
z = ~x;
endfunction
endinterface
module Module(interface y);
function z;
input T y;
z = y.x;
endfunction
integer x = 0;
initial begin
#1;
$display("x = %b", x);
$display("z(x) = %b", z(x));
$display("y.x = %b", y.x);
$display("y.z(x) = %b", y.z(x));
$display("y.z(y.x) = %b", y.z(y.x));
$display("y.z(z(y.x)) = %b", y.z(z(y.x)));
end
endmodule
module top;
Interface x();
initial x.x = 1;
Module y(x);
endmodule
+30
View File
@@ -0,0 +1,30 @@
module top;
generate
begin : x
integer x;
function z;
input x;
z = ~x;
endfunction
end
endgenerate
initial x.x = 1;
generate
begin : y
function z;
input x;
z = x;
endfunction
integer x = 0;
initial begin
#1;
$display("x = %b", x);
$display("z(x) = %b", z(x));
$display("y.x = %b", top.x.x);
$display("y.z(x) = %b", top.x.z(x));
$display("y.z(y.x) = %b", top.x.z(top.x.x));
$display("y.z(z(y.x)) = %b", top.x.z(z(top.x.x)));
end
end
endgenerate
endmodule
+12 -8
View File
@@ -1,12 +1,16 @@
module top;
wire [3:0] i_x;
reg [1:0] i_w;
assign i_x = 4'b1001;
initial i_w = 2'b10;
generate
begin : i
wire [3:0] x;
reg [1:0] w;
end
endgenerate
assign i.x = 4'b1001;
initial i.w = 2'b10;
initial begin
$display("%b", i_x[3]);
$display("%b", i_x[2]);
$display("%b", i_x[1]);
$display("%b", i_x[0]);
$display("%b", i.x[3]);
$display("%b", i.x[2]);
$display("%b", i.x[1]);
$display("%b", i.x[0]);
end
endmodule