Playing around with Quartus 10.0, and so far this is synthesizable. This code uses a generate block to create multiple modports such that I can easily connect many slaves to a single interface programmatically where the interface has one bit per slave in a single bus.
This creates a 6-to-1 multiplexer sourced from 6 latches. Each latch has its own preset, clear, and select, and they all use a shared data and enable input.
Note the use of $size. It could have been done in other ways I'm sure.
Note the use of 'slave_modport_gen' in the instantiation of the slaves. This is how to reference the separate modports that are created in the interface. The need for separate modports is b/c I need to control different bits of q_bus for each modport.
Note the use of .sel(sel_in[i]) in the modport port direction descriptions. This is an alias (aliased to sel inside the module), also required to have the same module be able to control the desired bit of q_bus.
`timescale 1ns/1ns
interface bus # (
parameter NUM_SLAVES = 1
) (
input [NUM_SLAVES - 1:0] sel_in,
input e_in,
input d_in,
input [NUM_SLAVES - 1:0] s_in,
input [NUM_SLAVES - 1:0] r_in,
output q_out
);
logic q_bus [NUM_SLAVES - 1:0];
modport master(
input sel_in,
output q_out,
input q_bus
);
genvar i;
generate
for(i = 0; i < NUM_SLAVES; i++) begin : slave_modport_gen
wire e_comb;
assign e_comb = sel_in[i] && e_in;
modport slave(
input .e(e_comb),
input .d(d_in),
input .s(s_in[i]),
input .r(r_in[i]),
output .q(q_bus[i])
);
end
endgenerate
endinterface
module master(
bus.master m
);
integer i;
always_comb begin
m.q_out = 0;
for(i = 0; i < $size(m.sel_in); i++) begin
if(m.sel_in[i])
m.q_out = m.q_bus[i];
end
end
endmodule
module slave (
interface s
);
always_latch begin
if(s.e)
s.q <= s.d;
if(s.s)
s.q <= 1;
if(s.r)
s.q <= 0;
end
endmodule
module top # (
parameter NUM_SLAVES = 6
) (
input [NUM_SLAVES - 1:0] sel_in,
input e_in,
input d_in,
input [NUM_SLAVES - 1:0] s_in,
input [NUM_SLAVES - 1:0] r_in,
output q_out
);
bus # (
.NUM_SLAVES(NUM_SLAVES)
) bus_inst(
.sel_in(sel_in),
.e_in(e_in),
.d_in(d_in),
.s_in(s_in),
.r_in(r_in),
.q_out(q_out)
);
master master_inst(bus_inst);
genvar i;
generate
for(i = 0; i < NUM_SLAVES; i++) begin : slave_gen
slave slave_inst(bus_inst.slave_modport_gen[i].slave);
end
endgenerate
endmodule
No comments:
Post a Comment