-
Notifications
You must be signed in to change notification settings - Fork 53
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
Simplify Calyx AXI wrapper -- xVALID
signals and reg invokes
#1846
Changes from all commits
e7b39e7
fd3a0e5
cb38574
203387f
534ecc0
46f7d7a
cabba39
9fbe03e
74d9d8f
e5b84be
6729dac
cdef8b6
a1d8e5a
51f91d3
4d80ca7
7725cc3
11c3bc3
736264b
2c7c241
21d13f9
7312254
e2e848f
4fed24a
6710f3f
f30b274
6a8d6a6
d084d3a
06db156
2cf9ed5
8cc10a0
8b99289
6328e0c
b3567d1
fe8f284
a13cd60
505ae00
3f6f129
ba5e1a4
d93d852
6fbc3ca
a6426a6
d2db261
3aa9722
d813517
58a9de6
cfd40d6
b26f0ea
96b9975
03e93a8
4a1291f
3abee21
94efbc9
7179097
2f841e8
618f9b6
7866017
c926cf8
4120ee3
8c29f01
14066a1
ecb5626
d40a066
297e60e
e6cc577
681c316
22926ab
04200f5
e24d114
b212c56
6fd6697
9d4fc22
e9e6317
5c51038
b6437d1
4fbdcc4
624e0d5
923fc5e
c7e3839
9fd9cd3
53c53d4
31b6986
eb9a817
02631c0
c7869e9
880b1a8
ab2a31a
4c1d9fb
ff5c2c9
3e7fe70
80c509a
01b7bd0
60462e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,32 +72,13 @@ component m_arread_channel( | |
|
||
ARVALID = is_arvalid.out; | ||
|
||
group deassert_val { | ||
is_arvalid.in = 1'b0; | ||
is_arvalid.write_en = 1'b1; | ||
deassert_val[done] = is_arvalid.done; | ||
} | ||
|
||
group reset_bt { | ||
bt_reg.in = 1'b0; | ||
bt_reg.write_en = 1'b1; | ||
reset_bt[done] = bt_reg.done; | ||
} | ||
|
||
group reset_was_high { | ||
arvalid_was_high.in = 1'b0; | ||
arvalid_was_high.write_en = 1'b1; | ||
reset_was_high[done] = arvalid_was_high.done; | ||
} | ||
|
||
// this asserts valid and defines all inputs correctly | ||
// because valid should not be deasserted until handshake occurs | ||
// this all needs to be one group | ||
// this contains blocking logic previously in its own group | ||
group do_ar_transfer { | ||
//assert ARVALID | ||
|
||
is_arvalid.in = !(is_arvalid.out & ARREADY) & !arvalid_was_high.out ? 1'b1; | ||
//assert ARVALID as long as this is the first time we are asserting it | ||
is_arvalid.in = !arvalid_was_high.out ? 1'b1; | ||
|
||
// TODO(nathanielnrn): in theory should be able to get rid of arvalid_was_high | ||
// but for now we will be explicit and reduce this in generation maybe. Not sure | ||
|
@@ -134,25 +115,6 @@ component m_arread_channel( | |
do_ar_transfer[done] = bt_reg.out; | ||
} | ||
|
||
|
||
//txn bookkeeping. | ||
//We are done performing reads when txn_count == txn_n | ||
group txn_count_init { | ||
txn_count.in = 32'b0; | ||
txn_count.write_en = 1'b1; | ||
txn_count_init[done] = txn_count.done; | ||
|
||
} | ||
|
||
group txn_len_init { | ||
// TODO(nathanielnrn):Parametrize this. | ||
// 7 is good for word wide data bus and 8 element vec_add We'd | ||
// expect 8 transfers. Number of transfers that occur is ARLEN + 1 | ||
txn_len.in = 8'd7; | ||
txn_len.write_en = 1'b1; | ||
txn_len_init[done] = txn_len.done; | ||
} | ||
|
||
group txn_incr { | ||
txn_adder.left = txn_count.out; | ||
txn_adder.right = 32'b1; | ||
|
@@ -172,16 +134,19 @@ component m_arread_channel( | |
control{ | ||
//XXX(nathanielnrn): What is best way to offer more flexiblity beyond just a counter? | ||
seq{ | ||
txn_count_init; | ||
txn_len_init; | ||
invoke txn_count(in=32'b0)(); | ||
// TODO(nathanielnrn):Parametrize this. | ||
// 7 is good for word wide data bus and 8 element vec_add We'd | ||
// expect 8 transfers. Number of transfers that occur is ARLEN + 1 | ||
invoke txn_len(in=8'd7)(); | ||
while perform_reads.out with check_reads_done{ | ||
seq{ | ||
par { | ||
reset_bt; | ||
reset_was_high; | ||
invoke bt_reg(in=1'b0)(); | ||
invoke arvalid_was_high(in=1'b0)(); | ||
} | ||
do_ar_transfer; | ||
deassert_val; | ||
invoke is_arvalid(in=1'b0)(); | ||
txn_incr; | ||
} | ||
} | ||
|
@@ -223,6 +188,7 @@ component m_read_channel( | |
curr_addr_adder = std_add(64); | ||
|
||
// block_transfer reg to avoid combinational loops | ||
// Used to block any servicing until handshake occurs. | ||
bt_reg = std_reg(1); | ||
|
||
} | ||
|
@@ -231,19 +197,6 @@ component m_read_channel( | |
RREADY = is_rdy.out; | ||
data_received.read_en = 1'b0; | ||
|
||
group init_n_RLAST { | ||
n_RLAST.in = 1'b1; | ||
n_RLAST.write_en = 1'b1; | ||
init_n_RLAST[done] = n_RLAST.done; | ||
} | ||
|
||
// Used to block any servicing until handshake occurs. | ||
group reset_bt { | ||
bt_reg.in = 1'b0; | ||
bt_reg.write_en = 1'b1; | ||
reset_bt[done] = bt_reg.done; | ||
} | ||
|
||
// NOTE: xVALID signals must be high until xREADY is high as well, so this works | ||
// because if xREADY is high (is_rdy.out) then RVALID being high makes 1 flip | ||
// and group will be done by bt_reg.out | ||
|
@@ -306,10 +259,10 @@ component m_read_channel( | |
} | ||
} | ||
control{ | ||
init_n_RLAST; | ||
invoke n_RLAST(in=1'b1)(); //init n_RLAST | ||
while n_RLAST.out{ | ||
seq{ | ||
reset_bt; | ||
invoke bt_reg(in=1'b0)(); //reset bt_reg | ||
block_transfer; | ||
receive_r_transfer; | ||
incr_curr_addr; | ||
|
@@ -473,32 +426,13 @@ component m_awwrite_channel( | |
|
||
AWVALID = is_awvalid.out; | ||
|
||
group deassert_val { | ||
is_awvalid.in = 1'b0; | ||
is_awvalid.write_en = 1'b1; | ||
deassert_val[done] = is_awvalid.done; | ||
} | ||
|
||
group reset_bt { | ||
bt_reg.in = 1'b0; | ||
bt_reg.write_en = 1'b1; | ||
reset_bt[done] = bt_reg.done; | ||
} | ||
|
||
|
||
group reset_was_high { | ||
awvalid_was_high.in = 1'b0; | ||
awvalid_was_high.write_en = 1'b1; | ||
reset_was_high[done] = awvalid_was_high.done; | ||
} | ||
|
||
// this asserts valid and defines all inputs correctly | ||
// because valid should not be deasserted until handshake occurs | ||
// this all needs to be one group | ||
// this contains blocking logic previously in its own group | ||
group do_aw_transfer { | ||
//assert AWVALID | ||
is_awvalid.in = !(is_awvalid.out & AWREADY) & !awvalid_was_high.out ? 1'b1; | ||
is_awvalid.in = !awvalid_was_high.out ? 1'b1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same thing as |
||
|
||
// TODO(nathanielnrn): in theory should be able to get rid of awvalid_was_high | ||
// but for now we will be explicit and reduce this in generation maybe. Not sure | ||
|
@@ -540,22 +474,6 @@ component m_awwrite_channel( | |
} | ||
|
||
|
||
//txn bookkeeping. | ||
//We are done performing reads when txn_count == txn_n | ||
group txn_count_init { | ||
txn_count.in = 32'b0; | ||
txn_count.write_en = 1'b1; | ||
txn_count_init[done] = txn_count.done; | ||
|
||
} | ||
|
||
group txn_len_init { | ||
//TODO(nathanielnrn): 15 is good for word wide data bus. We'd | ||
//expect 16 transfers. Number of transfers that occur is AWLEN + 1 | ||
txn_len.in = 8'd7; | ||
txn_len.write_en = 1'b1; | ||
txn_len_init[done] = txn_len.done; | ||
} | ||
|
||
group txn_incr { | ||
txn_adder.left = txn_count.out; | ||
|
@@ -575,16 +493,17 @@ component m_awwrite_channel( | |
control{ | ||
//XXX(nathanielnrn): What is best way to offer more flexiblity beyond just a counter? | ||
seq{ | ||
txn_count_init; | ||
txn_len_init; | ||
invoke txn_count(in=32'b0)(); | ||
//TODO(nathanielnrn):parameterize this number. 7(+1) gives us 8 elements | ||
invoke txn_len(in=8'd7)(); | ||
while perform_write_txns.out with check_writes_done{ | ||
seq{ | ||
par { | ||
reset_bt; | ||
reset_was_high; | ||
invoke bt_reg(in=1'b0)(); | ||
invoke awvalid_was_high(in=1'b0)(); | ||
} | ||
do_aw_transfer; | ||
deassert_val; | ||
invoke is_awvalid(in=1'b0)(); | ||
txn_incr; | ||
} | ||
} | ||
|
@@ -638,35 +557,15 @@ component m_write_channel( | |
|
||
WVALID = wvalid.out; | ||
|
||
group reset_curr_addr{ | ||
curr_addr.in = 64'b0; | ||
curr_addr.write_en = 1'b1; | ||
reset_curr_addr[done] = curr_addr.done; | ||
} | ||
|
||
group init_n_finished_last_trnsfr { | ||
n_finished_last_trnsfr.in = 1'b1; | ||
n_finished_last_trnsfr.write_en = 1'b1; | ||
init_n_finished_last_trnsfr[done] = n_finished_last_trnsfr.done; | ||
} | ||
|
||
//Used to block any servicing until handshake occurs. | ||
group reset_bt { | ||
bt_reg.in = 1'b0; | ||
bt_reg.write_en = 1'b1; | ||
reset_bt[done] = bt_reg.done; | ||
} | ||
|
||
//NOTE: xVALID signals must be high until xREADY is high as well, so this works | ||
//because if xREADY is high (is_rdy.out) then RVALID being high makes 1 flip | ||
//and group will be done by bt_reg.out | ||
group do_write_transfer { | ||
//set RREADY high | ||
//TODO (nathanielnrn): technically we can make RREADY depend on on RVALID (but not vice versa). | ||
//Could we simplify this we just making things ready when we are in | ||
//block_transfer && RVALID? | ||
|
||
//NOTE: wvalid.in = 1'b1; does not work, it leaves RREADY high for 2 cycles | ||
//NOTE: wvalid.in = 1'b1; does not work, it leaves WVALID high for 2 cycles | ||
// this both asserts and deasserts one cycle later | ||
wvalid.in = !(wvalid.out & WREADY & wvalid_was_high.out) ? 1'b1; | ||
// TODO(nathanielnrn): Can prob get rid of wvalid_was_high | ||
|
@@ -675,7 +574,7 @@ component m_write_channel( | |
|
||
//set to 1 after valid has been high even once | ||
wvalid_was_high.in = 1'b1; | ||
wvalid_was_high.write_en = !(wvalid.out & WREADY) & !wvalid_was_high.out ? 1'b1; | ||
wvalid_was_high.write_en = !(wvalid.out & WREADY & !wvalid_was_high.out) ? 1'b1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This partitions assignment to |
||
|
||
|
||
// set data output based on curr_addr register | ||
|
@@ -720,12 +619,11 @@ component m_write_channel( | |
control{ | ||
seq{ | ||
|
||
reset_curr_addr; | ||
//end writing to internal mem | ||
init_n_finished_last_trnsfr; | ||
invoke curr_addr(in=64'b0)(); //reset curr_addr | ||
invoke n_finished_last_trnsfr(in=1'b1)(); //init reg | ||
while n_finished_last_trnsfr.out{ | ||
seq{ | ||
reset_bt; | ||
invoke bt_reg(in=1'b0)(); | ||
do_write_transfer; | ||
par{ | ||
incr_curr_addr; | ||
|
@@ -757,11 +655,6 @@ component m_bresp_channel( | |
} | ||
wires{ | ||
BREADY = bready.out; | ||
group reset_bt_reg{ | ||
bt_reg.in = 1'b0; | ||
bt_reg.write_en = 1'b1; | ||
reset_bt_reg[done] = bt_reg.done; | ||
} | ||
|
||
// TODO(nathanielnrn): This is probably very unoptimal and takes multiple | ||
// cycles to simply do a handshake. Can probably be much better | ||
|
@@ -779,7 +672,7 @@ component m_bresp_channel( | |
} | ||
control{ | ||
seq{ | ||
reset_bt_reg; | ||
invoke bt_reg(in=1'b0)(); | ||
block_transfer; | ||
} | ||
} | ||
|
@@ -1003,49 +896,15 @@ component main( | |
m2_WID = 1'b0; | ||
m2_BID = 1'b0; | ||
|
||
group set_curr_to_base_addr_A0{ | ||
curr_addr_A0.in = base_addr_A0.out; | ||
curr_addr_A0.write_en = 1'b1; | ||
set_curr_to_base_addr_A0[done] = curr_addr_A0.done; | ||
} | ||
|
||
group init_base_addr_A0{ | ||
base_addr_A0.in = 64'b0; | ||
base_addr_A0.write_en = 1'b1; | ||
init_base_addr_A0[done] = base_addr_A0.done; | ||
} | ||
|
||
group set_curr_to_base_addr_B0{ | ||
curr_addr_B0.in = base_addr_B0.out; | ||
curr_addr_B0.write_en = 1'b1; | ||
set_curr_to_base_addr_B0[done] = curr_addr_B0.done; | ||
} | ||
|
||
group init_base_addr_B0{ | ||
base_addr_B0.in = 64'b0; | ||
base_addr_B0.write_en = 1'b1; | ||
init_base_addr_B0[done] = base_addr_B0.done; | ||
} | ||
|
||
group set_curr_to_base_addr_Sum0{ | ||
curr_addr_Sum0.in = base_addr_Sum0.out; | ||
curr_addr_Sum0.write_en = 1'b1; | ||
set_curr_to_base_addr_Sum0[done] = curr_addr_Sum0.done; | ||
} | ||
|
||
group init_base_addr_Sum0{ | ||
base_addr_Sum0.in = 64'b0; | ||
base_addr_Sum0.write_en = 1'b1; | ||
init_base_addr_Sum0[done] = base_addr_Sum0.done; | ||
} | ||
} | ||
control{ | ||
seq{ | ||
//read stuff | ||
par{ | ||
init_base_addr_A0; | ||
init_base_addr_B0; | ||
init_base_addr_Sum0; | ||
//init base_addresses | ||
invoke base_addr_A0(in = 64'b0)(); | ||
invoke base_addr_B0(in = 64'b0)(); | ||
invoke base_addr_Sum0(in = 64'b0)(); | ||
} | ||
par{ | ||
seq{ | ||
|
@@ -1063,7 +922,7 @@ component main( | |
ARBURST = m0_ARBURST | ||
); | ||
|
||
set_curr_to_base_addr_A0; | ||
invoke curr_addr_A0(in = base_addr_A0.out)(); //set curr_addr to base_address | ||
|
||
invoke A0_read_channel[data_received = A0, curr_addr = curr_addr_A0] | ||
( | ||
|
@@ -1093,7 +952,7 @@ component main( | |
ARBURST = m1_ARBURST | ||
); | ||
|
||
set_curr_to_base_addr_B0; | ||
invoke curr_addr_B0(in = base_addr_B0.out)(); //set curr_addr to base_address | ||
|
||
invoke B0_read_channel[data_received = B0, curr_addr = curr_addr_B0] | ||
( | ||
|
@@ -1121,7 +980,7 @@ component main( | |
ARBURST = m2_ARBURST | ||
); | ||
|
||
set_curr_to_base_addr_Sum0; | ||
invoke curr_addr_Sum0(in = base_addr_Sum0.out)(); //set curr_addr to base_address | ||
|
||
invoke Sum0_read_channel[data_received = Sum0, curr_addr = curr_addr_Sum0] | ||
( | ||
|
@@ -1162,7 +1021,7 @@ component main( | |
AWPROT = m0_AWPROT | ||
); | ||
|
||
set_curr_to_base_addr_A0; | ||
invoke curr_addr_A0(in = base_addr_A0.out)(); //set curr_addr to base_address | ||
|
||
invoke A0_write_channel[internal_mem = A0, curr_addr = curr_addr_A0, max_trnsfrs = max_trnsfrs] | ||
( | ||
|
@@ -1192,7 +1051,7 @@ component main( | |
AWPROT = m1_AWPROT | ||
); | ||
|
||
set_curr_to_base_addr_B0; | ||
invoke curr_addr_B0(in = base_addr_B0.out)(); //set curr_addr to base_address | ||
|
||
invoke B0_write_channel[internal_mem = B0, curr_addr = curr_addr_B0, max_trnsfrs = max_trnsfrs] | ||
( | ||
|
@@ -1223,7 +1082,7 @@ component main( | |
AWPROT = m2_AWPROT | ||
); | ||
|
||
set_curr_to_base_addr_Sum0; | ||
invoke curr_addr_Sum0(in = base_addr_Sum0.out)(); //set curr_addr to base_address | ||
|
||
invoke Sum0_write_channel[internal_mem = Sum0, curr_addr = curr_addr_Sum0, max_trnsfrs = max_trnsfrs] | ||
( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me like
is_arvalid.out & ARREADY
will always be true becauseis_arvalid.out
is always 0 as we calldeassert_val
in the control sequence:So we can simplify to just
!arvalid_was_high.out
as our guard