Skip to content

Commit 926ac8d

Browse files
authored
Merge pull request #285 from Ckaf/add_mux
add mux function
2 parents 39d0f9e + d92092c commit 926ac8d

16 files changed

Lines changed: 957 additions & 327 deletions

File tree

app/Main.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ defMicroarch ioSync = defineNetwork "net1" ioSync $ do
378378
}
379379
add "compare" CompareIO
380380
add "logicalUnit" LogicalUnitIO
381+
add "mux" MultiplexerIO
381382

382383
microarchWithProtos ioSync = defineNetwork "net1" ioSync $ do
383384
addCustomPrototype "fram{x}" (framWithSize 32) FramIO
@@ -394,3 +395,4 @@ microarchWithProtos ioSync = defineNetwork "net1" ioSync $ do
394395
}
395396
addPrototype "compare{x}" CompareIO
396397
addPrototype "logicalUnit{x}" LogicalUnitIO
398+
addPrototype "mux{x}" MultiplexerIO

examples/mux.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function muxf(a, b)
2+
local cond = 1
3+
local res = if_mux (cond, a, b)
4+
muxf(res, a)
5+
end
6+
7+
muxf(1, 0)

hdl/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ define test
88
$(shell which vvp) $(PWD)/$(3).out
99
endef
1010

11-
all: pu_accum pu_fram pu_mux pu_fifo pu_shift pu_div pu_multiplier pu_i2c pu_spi pu_compare
11+
all: pu_accum pu_fram pu_multiplexer pu_fifo pu_shift pu_div pu_multiplier pu_i2c pu_spi pu_compare
1212

1313
clean:
1414
$(RM) -r $(PWD)/*.vcd $(PWD)/*.out
@@ -23,8 +23,8 @@ pu_accum:
2323
pu_fram:
2424
$(call test,pu_fram.v,pu_fram_tb.v,test_pu_fram_tb)
2525

26-
pu_mux:
27-
$(call test,pu_mux.v,pu_mux_tb.v,test_pu_mux_tb)
26+
pu_multiplexer:
27+
$(call test,pu_multiplexer.v,pu_multiplexer_tb.v,test_pu_multiplexer_tb)
2828

2929
pu_fifo:
3030
$(call test,pu_fifo.v,pu_fifo_tb.v,test_pu_fifo_tb)

hdl/pu_multiplexer.v

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module pu_multiplexer #(
2+
parameter DATA_WIDTH = 32,
3+
parameter ATTR_WIDTH = 4,
4+
parameter SEL_WIDTH = 1
5+
)(
6+
input wire clk,
7+
input wire rst,
8+
input wire signal_wr,
9+
input wire signal_sel,
10+
input wire signal_oe,
11+
12+
input wire signed [DATA_WIDTH-1:0] data_in,
13+
input wire [ATTR_WIDTH-1:0] attr_in,
14+
output wire signed [DATA_WIDTH-1:0] data_out,
15+
output wire [ATTR_WIDTH-1:0] attr_out
16+
);
17+
reg signed [DATA_WIDTH-1:0] buffer [0:(2**SEL_WIDTH)-1];
18+
reg [SEL_WIDTH-1:0] sel_reg;
19+
reg [SEL_WIDTH-1:0] write_index = 0;
20+
reg is_prev_out = 0;
21+
22+
23+
integer i;
24+
25+
always @(posedge clk) begin
26+
if (signal_wr) begin
27+
if (is_prev_out) begin
28+
sel_reg <= 0;
29+
is_prev_out <= 0;
30+
buffer[0] <= data_in;
31+
write_index <= 1;
32+
end else begin
33+
buffer[write_index] <= data_in;
34+
write_index <= write_index + 1;
35+
end
36+
end
37+
38+
if (signal_sel) begin
39+
if (is_prev_out) begin
40+
write_index <= 0;
41+
is_prev_out <= 0;
42+
end
43+
sel_reg <= data_in;
44+
end
45+
46+
if (signal_oe) begin
47+
is_prev_out <= 1;
48+
end
49+
end
50+
51+
assign attr_out = 0;
52+
assign data_out = (signal_oe && (sel_reg < write_index))? buffer[sel_reg] : 0;
53+
54+
endmodule

hdl/pu_multiplexer_tb.v

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
module pu_multiplexer_tb();
2+
3+
parameter DATA_WIDTH = 32;
4+
parameter ATTR_WIDTH = 4;
5+
parameter SEL_WIDTH = 1;
6+
7+
reg clk;
8+
reg signal_wr;
9+
reg signal_sel;
10+
reg signal_oe;
11+
reg [DATA_WIDTH-1:0] data_in;
12+
reg [ATTR_WIDTH-1:0] attr_in;
13+
wire [DATA_WIDTH-1:0] data_out;
14+
wire [ATTR_WIDTH-1:0] attr_out;
15+
16+
pu_multiplexer #(
17+
.DATA_WIDTH(DATA_WIDTH),
18+
.ATTR_WIDTH(ATTR_WIDTH),
19+
.SEL_WIDTH(SEL_WIDTH))
20+
dut (
21+
.clk(clk),
22+
.signal_wr(signal_wr),
23+
.signal_sel(signal_sel),
24+
.signal_oe(signal_oe),
25+
.data_in(data_in),
26+
.attr_in(attr_in),
27+
.data_out(data_out),
28+
.attr_out(attr_out)
29+
);
30+
31+
initial begin
32+
clk = 0;
33+
forever #1 clk = ~clk;
34+
end
35+
36+
task automatic write_data;
37+
input [SEL_WIDTH-1:0] sel;
38+
input [DATA_WIDTH-1:0] data;
39+
input [ATTR_WIDTH-1:0] attr;
40+
begin
41+
@(posedge clk);
42+
signal_sel <= 1;
43+
data_in <= sel;
44+
@(posedge clk);
45+
signal_sel <= 0;
46+
47+
signal_wr <= 1;
48+
data_in <= data;
49+
attr_in <= attr;
50+
@(posedge clk);
51+
signal_wr <= 0;
52+
$display("[%0t] Write: sel=%0d, data=0x%h, attr=0x%h", $time, sel, data, attr);
53+
end
54+
endtask
55+
56+
task automatic check_output;
57+
input [SEL_WIDTH-1:0] expected_sel;
58+
input [DATA_WIDTH-1:0] expected_data;
59+
input [ATTR_WIDTH-1:0] expected_attr;
60+
begin
61+
@(posedge clk);
62+
signal_oe <= 1;
63+
@(posedge clk);
64+
if (data_out !== expected_data || attr_out !== expected_attr)
65+
$display("FAIL: sel=%0d, expected (0x%h, 0x%h), got (0x%h, 0x%h)",
66+
expected_sel, expected_data, expected_attr, data_out, attr_out);
67+
else
68+
$display("PASS: sel=%0d, data=0x%h, attr=0x%h",
69+
expected_sel, data_out, attr_out);
70+
signal_oe <= 0;
71+
@(posedge clk);
72+
end
73+
endtask
74+
75+
initial begin
76+
$dumpfile("pu_multiplexer_tb.vcd");
77+
$dumpvars(0, pu_multiplexer_tb);
78+
79+
signal_wr = 0;
80+
signal_sel = 0;
81+
signal_oe = 0;
82+
data_in = 0;
83+
attr_in = 0;
84+
85+
write_data(0, 32'hAAAA_AAAA, 4'hA);
86+
write_data(1, 32'h5555_5555, 4'h5);
87+
88+
write_data(0, 0, 0);
89+
check_output(0, 32'hAAAA_AAAA, 4'hA);
90+
91+
write_data(1, 0, 0);
92+
check_output(1, 32'h5555_5555, 4'h5);
93+
94+
@(posedge clk);
95+
signal_oe <= 0;
96+
@(posedge clk);
97+
if (data_out !== 0 || attr_out !== 0)
98+
$display("FAIL: Output not reset");
99+
else
100+
$display("PASS: Output reset");
101+
102+
write_data(0, 32'hDEAD_BEEF, 4'hF);
103+
check_output(0, 32'hDEAD_BEEF, 4'hF);
104+
105+
#100;
106+
$finish;
107+
end
108+
109+
endmodule

0 commit comments

Comments
 (0)