Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393
Commits
f948ab8f
Commit
f948ab8f
authored
Jan 21, 2015
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
next snapshot
parent
b8040cc2
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
273 additions
and
117 deletions
+273
-117
address_map.txt
address_map.txt
+4
-0
ddr_refresh.v
memctrl/ddr_refresh.v
+17
-8
memctrl16.v
memctrl/memctrl16.v
+225
-102
scheduler16.v
memctrl/scheduler16.v
+6
-6
mcontr_sequencer.v
phy/mcontr_sequencer.v
+1
-1
x393.v
x393.v
+20
-0
No files found.
address_map.txt
View file @
f948ab8f
...
...
@@ -28,6 +28,10 @@
parameter MCONTR_PHY_16BIT_WBUF_DELAY = 'h2, // 4 bits - extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
parameter MCONTR_PHY_16BIT_EXTRA_REL = 'h3, // 1 bit - set extra parameters (currently just inv_clk_div)
parameter MCONTR_PHY_STATUS_CNTRL = 'h4, // 8 bits - write to status control
0x1060..106f: arbiter priority data
parameter MCONTR_ARBIT_ADDR = 'h060, // Address to set channel priorities
parameter MCONTR_ARBIT_ADDR_MASK = 'h3f0, // Address mask to set channel priorities
// Status read address
parameter STATUS_ADDR = 'h1400, // AXI write address of status read registers
parameter STATUS_ADDR_MASK = 'h1400, // AXI write address of status registers
...
...
memctrl/ddr_refresh.v
View file @
f948ab8f
...
...
@@ -23,10 +23,10 @@
module
ddr_refresh
(
input
rst
,
input
clk
,
input
[
7
:
0
]
refresh_period
,
// in 16*clk
input
[
7
:
0
]
refresh_period
,
// in 16*clk
, 0 - disable refresh, turn off requests
input
set
,
// and reset counters
output
want
,
// turns off next cycle after grant (or stays on if more are needed)
output
need
,
output
reg
want
,
// turns off next cycle after grant (or stays on if more are needed)
output
reg
need
,
input
grant
// 1 cycle
)
;
reg
[
3
:
0
]
pre_div
;
...
...
@@ -35,11 +35,14 @@ module ddr_refresh(
reg
cry
;
wire
over
=
(
period_cntr
==
0
)
&&
cry
;
reg
refresh_due
;
assign
want
=
pending_rq
!=
0
;
assign
need
=
pending_rq
[
4
:
3
]
!=
0
;
reg
en_refresh
;
always
@
(
posedge
rst
or
posedge
clk
)
begin
if
(
rst
)
en_refresh
<=
0
;
else
if
(
set
)
en_refresh
<=
(
refresh_period
!=
0
)
;
if
(
rst
)
pre_div
<=
0
;
else
if
(
set
)
pre_div
<=
0
;
else
if
(
set
||
!
en_refresh
)
pre_div
<=
0
;
else
pre_div
<=
pre_div
+
1
;
if
(
rst
)
cry
<=
0
;
...
...
@@ -58,6 +61,12 @@ module ddr_refresh(
else
if
(
set
)
pending_rq
<=
0
;
else
if
(
refresh_due
&&
!
grant
)
pending_rq
<=
pending_rq
+
1
;
else
if
(
!
refresh_due
&&
grant
)
pending_rq
<=
pending_rq
-
1
;
if
(
rst
)
want
<=
0
;
else
want
<=
en_refresh
&&
(
pending_rq
!=
0
)
;
if
(
rst
)
need
<=
0
;
else
need
<=
en_refresh
&&
(
pending_rq
[
4
:
3
]
!=
0
)
;
end
endmodule
memctrl/memctrl16.v
View file @
f948ab8f
...
...
@@ -57,6 +57,11 @@ module memctrl16 #(
parameter
MCONTR_PHY_16BIT_WBUF_DELAY
=
'h2
,
// 4? bits - extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
parameter
MCONTR_PHY_16BIT_EXTRA
=
'h3
,
// ? bits - set extra parameters (currently just inv_clk_div)
parameter
MCONTR_PHY_STATUS_CNTRL
=
'h4
,
// write to status control (8-bit)
//0x1060..106f: arbiter priority data
parameter
MCONTR_ARBIT_ADDR
=
'h060
,
// Address to set channel priorities
parameter
MCONTR_ARBIT_ADDR_MASK
=
'h3f0
,
// Address mask to set channel priorities
// Status read address
parameter
MCONTR_PHY_STATUS_REG_ADDR
=
'h0
,
// 8 or less bits: status register address to use for memory controller phy
parameter
CHNBUF_READ_LATENCY
=
0
,
// external channel buffer extra read latency ( 0 - data available next cycle after re (but prev. data))
...
...
@@ -109,14 +114,6 @@ module memctrl16 #(
input
clk_in
,
input
rst_in
,
output
mclk
,
// global clock, half DDR3 clock, synchronizes all I/O thorough the command port
/*
input [15:0] want_rq, // both want_rq and need_rq should go inactive after being granted
input [15:0] need_rq,
output [15:0] channel_pgm_en, // channel can program sequence data
input [511:0] seq_data, //16x32 data to be written to the sequencer (and start address for software-based sequencer)
input [15:0] seq_wr, // strobe for writing sequencer data (address is autoincremented)
input [15:0] seq_done, // channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
*/
// programming interface
input
[
7
:
0
]
cmd_ad
,
// byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
input
cmd_stb
,
// strobe (with first byte) for the command a/d
...
...
@@ -124,12 +121,18 @@ module memctrl16 #(
output
status_rq
,
// input request to send status downstream
input
status_start
,
// Acknowledge of the first status packet byte (address)
// command port 0 (filled by software - 32w->32r) - used for mode set, refresh, write levelling, ...
input
cmd0_clk
,
// clock to write commend sequencer from PS
input
cmd0_we
,
// write enble to write commend sequencer from PS
input
[
9
:
0
]
cmd0_addr
,
// address write commend sequencer from PS
input
[
31
:
0
]
cmd0_data
,
// data to write commend sequencer from PS
// channel interfaces TODO: move request/grant here, add "done"
// channel 0 interface
`ifdef
def_enable_mem_chn0
input
want_rq0
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq0
,
output
channel_pgm_en0
,
// channel can program sequence data
output
reg
channel_pgm_en0
,
// channel can program sequence data
input
[
31
:
0
]
seq_data0
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr0
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done0
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -148,7 +151,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn1
input
want_rq1
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq1
,
output
channel_pgm_en1
,
// channel can program sequence data
output
reg
channel_pgm_en1
,
// channel can program sequence data
input
[
31
:
0
]
seq_data1
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr1
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done1
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -167,7 +170,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn2
input
want_rq2
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq2
,
output
channel_pgm_en2
,
// channel can program sequence data
output
reg
channel_pgm_en2
,
// channel can program sequence data
input
[
31
:
0
]
seq_data2
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr2
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done2
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -186,7 +189,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn3
input
want_rq3
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq3
,
output
channel_pgm_en3
,
// channel can program sequence data
output
reg
channel_pgm_en3
,
// channel can program sequence data
input
[
31
:
0
]
seq_data3
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr3
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done3
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -205,7 +208,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn4
input
want_rq4
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq4
,
output
channel_pgm_en4
,
// channel can program sequence data
output
reg
channel_pgm_en4
,
// channel can program sequence data
input
[
31
:
0
]
seq_data4
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr4
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done4
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -224,7 +227,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn5
input
want_rq5
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq5
,
output
channel_pgm_en5
,
// channel can program sequence data
output
reg
channel_pgm_en5
,
// channel can program sequence data
input
[
31
:
0
]
seq_data5
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr5
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done5
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -243,7 +246,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn6
input
want_rq6
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq6
,
output
channel_pgm_en6
,
// channel can program sequence data
output
reg
channel_pgm_en6
,
// channel can program sequence data
input
[
31
:
0
]
seq_data6
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr6
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done6
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -262,7 +265,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn7
input
want_rq7
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq7
,
output
channel_pgm_en7
,
// channel can program sequence data
output
reg
channel_pgm_en7
,
// channel can program sequence data
input
[
31
:
0
]
seq_data7
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr7
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done7
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -281,7 +284,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn8
input
want_rq8
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq8
,
output
channel_pgm_en8
,
// channel can program sequence data
output
reg
channel_pgm_en8
,
// channel can program sequence data
input
[
31
:
0
]
seq_data8
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr8
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done8
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -300,7 +303,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn9
input
want_rq9
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq9
,
output
channel_pgm_en9
,
// channel can program sequence data
output
reg
channel_pgm_en9
,
// channel can program sequence data
input
[
31
:
0
]
seq_data9
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr9
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done9
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -319,7 +322,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn10
input
want_rq10
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq10
,
output
channel_pgm_en10
,
// channel can program sequence data
output
reg
channel_pgm_en10
,
// channel can program sequence data
input
[
31
:
0
]
seq_data10
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr10
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done10
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -338,7 +341,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn11
input
want_rq11
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq11
,
output
channel_pgm_en11
,
// channel can program sequence data
output
reg
channel_pgm_en11
,
// channel can program sequence data
input
[
31
:
0
]
seq_data11
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr11
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done11
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -357,7 +360,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn12
input
want_rq12
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq12
,
output
channel_pgm_en12
,
// channel can program sequence data
output
reg
channel_pgm_en12
,
// channel can program sequence data
input
[
31
:
0
]
seq_data12
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr12
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done12
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -376,7 +379,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn13
input
want_rq13
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq13
,
output
channel_pgm_en13
,
// channel can program sequence data
output
reg
channel_pgm_en13
,
// channel can program sequence data
input
[
31
:
0
]
seq_data13
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr13
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done13
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -395,7 +398,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn14
input
want_rq14
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq14
,
output
channel_pgm_en14
,
// channel can program sequence data
output
reg
channel_pgm_en14
,
// channel can program sequence data
input
[
31
:
0
]
seq_data14
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr14
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done14
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -414,7 +417,7 @@ module memctrl16 #(
`ifdef
def_enable_mem_chn15
input
want_rq15
,
// both want_rq and need_rq should go inactive after being granted
input
need_rq15
,
output
channel_pgm_en15
,
// channel can program sequence data
output
reg
channel_pgm_en15
,
// channel can program sequence data
input
[
31
:
0
]
seq_data15
,
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
input
seq_wr15
,
// strobe for writing sequencer data (address is autoincremented)
input
seq_done15
,
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
...
...
@@ -471,19 +474,11 @@ wire rst=rst_in; // TODO: decide where toi generate
wire
[
15
:
0
]
want_rq
;
// both want_rq and need_rq should go inactive after being granted
wire
[
15
:
0
]
need_rq
;
wire
[
15
:
0
]
channel_pgm_en
;
// channel can program sequence data
wire
[
511
:
0
]
seq_data
;
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
wire
[
15
:
0
]
seq_wr
;
// strobe for writing sequencer data (address is autoincremented)
wire
[
15
:
0
]
seq_done
;
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
/*
input [15:0] want_rq, // both want_rq and need_rq should go inactive after being granted
input [15:0] need_rq,
output [15:0] channel_pgm_en, // channel can program sequence data
input [511:0] seq_data, //16x32 data to be written to the sequencer (and start address for software-based sequencer)
input [15:0] seq_wr, // strobe for writing sequencer data (address is autoincremented)
input [15:0] seq_done, // channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
*/
reg
[
31
:
0
]
seq_data
;
//16x32 data to be written to the sequencer (and start address for software-based sequencer)
reg
seq_wr
;
// strobe for writing sequencer data (address is autoincremented)
reg
seq_done
;
// channel sequencer data is written. If no seq_wr pulses before seq_done, seq_data contains software sequencer start address
// status data from phy (sequencer)
wire
[
7
:
0
]
status_ad_phy
;
...
...
@@ -494,6 +489,14 @@ wire rst=rst_in; // TODO: decide where toi generate
wire
[
7
:
0
]
status_ad_mcontr
;
wire
status_rq_mcontr
;
wire
status_start_mcontr
;
wire
en_schedul
;
// enable channel arbitration, needs to be disabled before next access can be scheduled
wire
need
;
// granted access is "needed" one, not just "wanted"
wire
grant
;
// single-cycle granted channel access
wire
[
3
:
0
]
grant_chn
;
// granted channel number, valid with grant, stays valid until en_schedul is deasserted
wire
[
3
:
0
]
priority_addr
;
// channel address to program priority
wire
[
15
:
0
]
priority_data
;
// priority data for the channel
wire
priority_en
;
// enable programming priority data (use different clock?)
// TODO: implement
assign
status_ad_mcontr
=
0
;
assign
status_rq_mcontr
=
0
;
...
...
@@ -511,10 +514,94 @@ wire rst=rst_in; // TODO: decide where toi generate
.
rq_out
(
status_rq
)
,
// output
.
start_out
(
status_start
)
// input
)
;
// generate 16-bit data commands (and set defaults to registers)
cmd_deser
#(
.
ADDR
(
MCONTR_ARBIT_ADDR
)
,
.
ADDR_MASK
(
MCONTR_ARBIT_ADDR_MASK
)
,
.
NUM_CYCLES
(
4
)
,
.
ADDR_WIDTH
(
4
)
,
.
DATA_WIDTH
(
16
)
)
cmd_deser_mcontr_16bit_i
(
.
rst
(
rst
)
,
// input
.
clk
(
mclk
)
,
// input
.
ad
(
cmd_ad
)
,
// input[7:0]
.
stb
(
cmd_stb
)
,
// input
.
addr
(
priority_addr
)
,
// output[15:0]
.
data
(
priority_data
)
,
// output[31:0]
.
we
(
priority_en
)
// output
)
;
scheduler16
#(
.
width
(
16
)
)
scheduler16_i
(
.
rst
(
rst
)
,
// input
.
clk
(
mclk
)
,
// input
.
want_rq
(
want_rq
)
,
// input[15:0]
.
need_rq
(
need_rq
)
,
// input[15:0]
.
en_schedul
(
en_schedul
)
,
// input
.
need
(
need
)
,
// output
.
grant
(
grant
)
,
// output
.
grant_chn
(
grant_chn
)
,
// output[3:0]
.
pgm_addr
(
priority_addr
)
,
// input[3:0]
.
pgm_data
(
priority_data
)
,
// input[15:0]
.
pgm_en
(
priority_en
)
// input
)
;
reg
[
3
:
0
]
cnm_wr_chn
;
// channel granted write access to command sequencer memory
reg
[
9
:
0
]
cmd_addr_cur
;
// current address in the command sequencer memory bank1 (PL)
reg
[
10
:
0
]
cmd_addr_start
;
// sequencer start address (including bank 0/1)
reg
grant_r
;
reg
cmd_seq_set
;
// some command sequencer data was set (so use it)
always
@
(
posedge
rst
or
posedge
mclk
)
begin
if
(
rst
)
grant_r
<=
0
;
else
grant_r
<=
grant
;
if
(
rst
)
cmd_seq_set
<=
0
;
else
if
(
grant_r
)
cmd_seq_set
<=
0
;
else
if
(
seq_wr
)
cmd_seq_set
<=
1
;
if
(
rst
)
cnm_wr_chn
<=
0
;
else
if
(
grant
)
cnm_wr_chn
<=
grant_chn
;
if
(
rst
)
cmd_addr_cur
<=
0
;
else
if
(
seq_wr
)
cmd_addr_cur
<=
cmd_addr_cur
+
1
;
if
(
rst
)
cmd_addr_start
<=
0
;
else
if
(
grant_r
)
cmd_addr_start
<=
{
1'b1
,
cmd_addr_cur
};
// address in PL bank
else
if
(
!
cmd_seq_set
&&
seq_done
)
cmd_addr_start
<=
{
1'b0
,
seq_data
[
9
:
0
]
};
// address in PL bank
// add refresh address here?
end
// Add a few 16-bit write registers - refresh, separate refresh enable,
// refresh sequnecer address
// something else?
// TODO: command/refresh arbiter
//Manual channels (i.e. setap/recalibrate comands) - outside, through channels
wire
refresh_want
;
wire
refresh_need
;
reg
refresh_grant
;
// assign run_seq_rq_in = refresh_en && refresh_need; // higher priority request input
ddr_refresh
ddr_refresh_i
(
.
rst
(
rst
)
,
// input
.
clk
(
mclk
)
,
// input
.
refresh_period
(
refresh_period
[
7
:
0
])
,
// input[7:0]
.
set
(
refresh_set
)
,
// input
.
want
(
refresh_want
)
,
// output
.
need
(
refresh_need
)
,
// output
.
grant
(
refresh_grant
)
// input
)
;
always
@
(
posedge
rst
or
posedge
mclk
)
begin
if
(
rst
)
refresh_grant
<=
0
;
else
refresh_grant
<=
!
refresh_grant
&&
refresh_en
&&
!
run_busy
&&
!
axi_run_seq
&&
(
refresh_need
||
(
refresh_want
&&
!
run_seq_rq_gen
))
;
end
/* Instance template for module mcontr_sequencer */
mcontr_sequencer
#(
.
DLY_LD
(
DLY_LD
)
,
.
DLY_LD_MASK
(
DLY_LD_MASK
)
,
...
...
@@ -589,15 +676,15 @@ wire rst=rst_in; // TODO: decide where toi generate
.
rst_in
(
rst_in
)
,
// axi_rst), // input TODO: move buffer outside?
.
mclk
(
mclk
)
,
// output
.
cmd0_clk
(
axi_aclk
)
,
// input
.
cmd0_we
(
en_cmd0_wr
)
,
// input
.
cmd0_addr
(
axiwr_bram_waddr
[
9
:
0
])
,
// input[9:0]
.
cmd0_data
(
axiwr_bram_wdata
[
31
:
0
])
,
// input[31:0]
.
cmd0_clk
(
cmd0_clk
)
,
// input
.
cmd0_we
(
cmd0_we
)
,
// input
.
cmd0_addr
(
cmd0_addr
[
9
:
0
])
,
// input[9:0]
.
cmd0_data
(
cmd0_data
[
31
:
0
])
,
// input[31:0]
.
cmd1_clk
(
mclk
)
,
// input
// TODO: add - from PL generation of the command sequences
.
cmd1_we
(
1'b0
)
,
// input
.
cmd1_addr
(
10'b0
)
,
// input[9:0]
.
cmd1_data
(
32'b0
)
,
// input[31:0]
.
cmd1_we
(
seq_wr
)
,
// input
.
cmd1_addr
(
cmd_addr_cur
)
,
// input[9:0]
.
cmd1_data
(
seq_data
)
,
// input[31:0]
.
run_addr
(
run_addr
[
10
:
0
])
,
// input[10:0]
.
run_chn
(
run_chn
[
3
:
0
])
,
// input[3:0]
...
...
@@ -799,128 +886,164 @@ wire rst=rst_in; // TODO: decide where toi generate
// combining channel control signals to buses
`ifndef
def_enable_mem_chn0
wire
want_rq0
=
0
,
need_rq0
=
0
,
seq_wr0
=
0
,
seq_done0
=
0
;
wire
[
31
:
0
]
seq_data0
=
0
;
wire
want_rq0
=
0
,
need_rq0
=
0
;
`endif
`ifndef
def_enable_mem_chn1
wire
want_rq1
=
0
,
need_rq1
=
0
,
seq_wr1
=
0
,
seq_done1
=
0
;
wire
[
31
:
0
]
seq_data1
=
0
;
wire
want_rq1
=
0
,
need_rq1
=
0
;
`endif
`ifndef
def_enable_mem_chn2
wire
want_rq2
=
0
,
need_rq2
=
0
,
seq_wr2
=
0
,
seq_done2
=
0
;
wire
[
31
:
0
]
seq_data2
=
0
;
wire
want_rq2
=
0
,
need_rq2
=
0
;
`endif
`ifndef
def_enable_mem_chn3
wire
want_rq3
=
0
,
need_rq3
=
0
,
seq_wr3
=
0
,
seq_done3
=
0
;
wire
[
31
:
0
]
seq_data3
=
0
;
wire
want_rq3
=
0
,
need_rq3
=
0
;
`endif
`ifndef
def_enable_mem_chn4
wire
want_rq4
=
0
,
need_rq4
=
0
,
seq_wr4
=
0
,
seq_done4
=
0
;
wire
[
31
:
0
]
seq_data4
=
0
;
wire
want_rq4
=
0
,
need_rq4
=
0
;
`endif
`ifndef
def_enable_mem_chn5
wire
want_rq5
=
0
,
need_rq5
=
0
,
seq_wr5
=
0
,
seq_done5
=
0
;
wire
[
31
:
0
]
seq_data5
=
0
;
wire
want_rq5
=
0
,
need_rq5
=
0
;
`endif
`ifndef
def_enable_mem_chn6
wire
want_rq6
=
0
,
need_rq6
=
0
,
seq_wr6
=
0
,
seq_done6
=
0
;
wire
[
31
:
0
]
seq_data6
=
0
;
wire
want_rq6
=
0
,
need_rq6
=
0
;
`endif
`ifndef
def_enable_mem_chn7
wire
want_rq7
=
0
,
need_rq7
=
0
,
seq_wr7
=
0
,
seq_done7
=
0
;
wire
[
31
:
0
]
seq_data7
=
0
;
wire
want_rq7
=
0
,
need_rq7
=
0
;
`endif
`ifndef
def_enable_mem_chn8
wire
want_rq8
=
0
,
need_rq8
=
0
,
seq_wr8
=
0
,
seq_done8
=
0
;
wire
[
31
:
0
]
seq_data8
=
0
;
wire
want_rq8
=
0
,
need_rq8
=
0
;
`endif
`ifndef
def_enable_mem_chn9
wire
want_rq9
=
0
,
need_rq9
=
0
,
seq_wr9
=
0
,
seq_done9
=
0
;
wire
[
31
:
0
]
seq_data9
=
0
;
wire
want_rq9
=
0
,
need_rq9
=
0
;
`endif
`ifndef
def_enable_mem_chn10
wire
want_rq10
=
0
,
need_rq10
=
0
,
seq_wr10
=
0
,
seq_done10
=
0
;
wire
[
31
:
0
]
seq_data10
=
0
;
wire
want_rq10
=
0
,
need_rq10
=
0
;
`endif
`ifndef
def_enable_mem_chn11
wire
want_rq11
=
0
,
need_rq11
=
0
,
seq_wr11
=
0
,
seq_done11
=
0
;
wire
[
31
:
0
]
seq_data11
=
0
;
wire
want_rq11
=
0
,
need_rq11
=
0
;
`endif
`ifndef
def_enable_mem_chn12
wire
want_rq12
=
0
,
need_rq12
=
0
,
seq_wr12
=
0
,
seq_done12
=
0
;
wire
[
31
:
0
]
seq_data12
=
0
;
wire
want_rq12
=
0
,
need_rq12
=
0
;
`endif
`ifndef
def_enable_mem_chn13
wire
want_rq13
=
0
,
need_rq13
=
0
,
seq_wr13
=
0
,
seq_done13
=
0
;
wire
[
31
:
0
]
seq_data13
=
0
;
wire
want_rq13
=
0
,
need_rq13
=
0
;
`endif
`ifndef
def_enable_mem_chn14
wire
want_rq14
=
0
,
need_rq14
=
0
,
seq_wr14
=
0
,
seq_done14
=
0
;
wire
[
31
:
0
]
seq_data14
=
0
;
wire
want_rq14
=
0
,
need_rq14
=
0
;
`endif
`ifndef
def_enable_mem_chn15
wire
want_rq15
=
0
,
need_rq15
=
0
,
seq_wr15
=
0
,
seq_done15
=
0
;
wire
[
31
:
0
]
seq_data15
=
0
;
wire
want_rq15
=
0
,
need_rq15
=
0
;
`endif
assign
want_rq
[
15
:
0
]
=
{
want_rq15
,
want_rq14
,
want_rq13
,
want_rq12
,
want_rq11
,
want_rq10
,
want_rq9
,
want_rq8
,
want_rq7
,
want_rq6
,
want_rq5
,
want_rq4
,
want_rq3
,
want_rq2
,
want_rq1
,
want_rq0
};
assign
need_rq
[
15
:
0
]
=
{
need_rq15
,
need_rq14
,
need_rq13
,
need_rq12
,
need_rq11
,
need_rq10
,
need_rq9
,
need_rq8
,
need_rq7
,
need_rq6
,
need_rq5
,
need_rq4
,
need_rq3
,
need_rq2
,
need_rq1
,
need_rq0
};
assign
seq_wr
[
15
:
0
]
=
{
seq_wr15
,
seq_wr14
,
seq_wr13
,
seq_wr12
,
seq_wr11
,
seq_wr10
,
seq_wr9
,
seq_wr8
,
seq_wr7
,
seq_wr6
,
seq_wr5
,
seq_wr4
,
seq_wr3
,
seq_wr2
,
seq_wr1
,
seq_wr0
};
assign
seq_done
[
15
:
0
]
=
{
seq_done15
,
seq_done14
,
seq_done13
,
seq_done12
,
seq_done11
,
seq_done10
,
seq_done9
,
seq_done8
,
seq_done7
,
seq_done6
,
seq_done5
,
seq_done4
,
seq_done3
,
seq_done2
,
seq_done1
,
seq_done0
};
assign
seq_data
[
511
:
0
]
=
{
seq_data15
,
seq_data14
,
seq_data13
,
seq_data12
,
seq_data11
,
seq_data10
,
seq_data9
,
seq_data8
,
seq_data7
,
seq_data6
,
seq_data5
,
seq_data4
,
seq_data3
,
seq_data2
,
seq_data1
,
seq_data0
};
always
@
(
posedge
rst
or
posedge
mclk
)
begin
if
(
rst
)
begin
seq_data
<=
0
;
seq_wr
<=
0
;
seq_done
<=
0
;
end
else
begin
case
(
cnm_wr_chn
)
`ifdef
def_enable_mem_chn0
4'h0
:
begin
seq_data
<=
seq_data0
;
seq_wr
<=
seq_wr0
;
seq_done
<=
seq_done0
;
end
`endif
`ifdef
def_enable_mem_chn1
4'd1
:
begin
seq_data
<=
seq_data1
;
seq_wr
<=
seq_wr1
;
seq_done
<=
seq_done1
;
end
`endif
`ifdef
def_enable_mem_chn2
4'd2
:
begin
seq_data
<=
seq_data2
;
seq_wr
<=
seq_wr2
;
seq_done
<=
seq_done2
;
end
`endif
`ifdef
def_enable_mem_chn3
4'd3
:
begin
seq_data
<=
seq_data3
;
seq_wr
<=
seq_wr3
;
seq_done
<=
seq_done3
;
end
`endif
`ifdef
def_enable_mem_chn4
4'd4
:
begin
seq_data
<=
seq_data4
;
seq_wr
<=
seq_wr4
;
seq_done
<=
seq_done4
;
end
`endif
`ifdef
def_enable_mem_chn5
4'd5
:
begin
seq_data
<=
seq_data5
;
seq_wr
<=
seq_wr5
;
seq_done
<=
seq_done5
;
end
`endif
`ifdef
def_enable_mem_chn6
4'd6
:
begin
seq_data
<=
seq_data6
;
seq_wr
<=
seq_wr6
;
seq_done
<=
seq_done6
;
end
`endif
`ifdef
def_enable_mem_chn7
4'd7
:
begin
seq_data
<=
seq_data7
;
seq_wr
<=
seq_wr7
;
seq_done
<=
seq_done7
;
end
`endif
`ifdef
def_enable_mem_chn8
4'd8
:
begin
seq_data
<=
seq_data8
;
seq_wr
<=
seq_wr8
;
seq_done
<=
seq_done8
;
end
`endif
`ifdef
def_enable_mem_chn9
4'd9
:
begin
seq_data
<=
seq_data9
;
seq_wr
<=
seq_wr9
;
seq_done
<=
seq_done9
;
end
`endif
`ifdef
def_enable_mem_chn10
4'd10
:
begin
seq_data
<=
seq_data10
;
seq_wr
<=
seq_wr10
;
seq_done
<=
seq_done10
;
end
`endif
`ifdef
def_enable_mem_chn11
4'd11
:
begin
seq_data
<=
seq_data11
;
seq_wr
<=
seq_wr11
;
seq_done
<=
seq_done11
;
end
`endif
`ifdef
def_enable_mem_chn12
4'd12
:
begin
seq_data
<=
seq_data12
;
seq_wr
<=
seq_wr12
;
seq_done
<=
seq_done12
;
end
`endif
`ifdef
def_enable_mem_chn13
4'd13
:
begin
seq_data
<=
seq_data13
;
seq_wr
<=
seq_wr13
;
seq_done
<=
seq_done13
;
end
`endif
`ifdef
def_enable_mem_chn14
4'd14
:
begin
seq_data
<=
seq_data14
;
seq_wr
<=
seq_wr14
;
seq_done
<=
seq_done14
;
end
`endif
`ifdef
def_enable_mem_chn15
4'd15
:
begin
seq_data
<=
seq_data15
;
seq_wr
<=
seq_wr15
;
seq_done
<=
seq_done15
;
end
`endif
endcase
end
end
`ifdef
def_enable_mem_chn0
a
ssign
channel_pgm_en0
=
channel_pgm_en
[
0
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en0
<=
grant
&&
(
grant_chn
==
0
)
;
`endif
`ifdef
def_enable_mem_chn1
a
ssign
channel_pgm_en1
=
channel_pgm_en
[
1
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en1
<=
grant
&&
(
grant_chn
==
1
)
;
`endif
`ifdef
def_enable_mem_chn2
a
ssign
channel_pgm_en2
=
channel_pgm_en
[
2
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en2
<=
grant
&&
(
grant_chn
==
2
)
;
`endif
`ifdef
def_enable_mem_chn3
a
ssign
channel_pgm_en3
=
channel_pgm_en
[
3
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en3
<=
grant
&&
(
grant_chn
==
3
)
;
`endif
`ifdef
def_enable_mem_chn4
a
ssign
channel_pgm_en4
=
channel_pgm_en
[
4
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en4
<=
grant
&&
(
grant_chn
==
4
)
;
`endif
`ifdef
def_enable_mem_chn5
a
ssign
channel_pgm_en5
=
channel_pgm_en
[
5
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en5
<=
grant
&&
(
grant_chn
==
5
)
;
`endif
`ifdef
def_enable_mem_chn6
a
ssign
channel_pgm_en6
=
channel_pgm_en
[
6
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en6
<=
grant
&&
(
grant_chn
==
6
)
;
`endif
`ifdef
def_enable_mem_chn7
a
ssign
channel_pgm_en7
=
channel_pgm_en
[
7
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en7
<=
grant
&&
(
grant_chn
==
7
)
;
`endif
`ifdef
def_enable_mem_chn8
a
ssign
channel_pgm_en8
=
channel_pgm_en
[
8
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en8
<=
grant
&&
(
grant_chn
==
8
)
;
`endif
`ifdef
def_enable_mem_chn9
a
ssign
channel_pgm_en9
=
channel_pgm_en
[
9
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en9
<=
grant
&&
(
grant_chn
==
9
)
;
`endif
`ifdef
def_enable_mem_chn10
a
ssign
channel_pgm_en10
=
channel_pgm_en
[
10
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en10
<=
grant
&&
(
grant_chn
==
10
)
;
`endif
`ifdef
def_enable_mem_chn11
a
ssign
channel_pgm_en11
=
channel_pgm_en
[
11
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en11
<=
grant
&&
(
grant_chn
==
11
)
;
`endif
`ifdef
def_enable_mem_chn12
a
ssign
channel_pgm_en12
=
channel_pgm_en
[
12
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en12
<=
grant
&&
(
grant_chn
==
12
)
;
`endif
`ifdef
def_enable_mem_chn13
a
ssign
channel_pgm_en13
=
channel_pgm_en
[
13
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en13
<=
grant
&&
(
grant_chn
==
13
)
;
`endif
`ifdef
def_enable_mem_chn14
a
ssign
channel_pgm_en14
=
channel_pgm_en
[
14
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en14
<=
grant
&&
(
grant_chn
==
14
)
;
`endif
`ifdef
def_enable_mem_chn15
a
ssign
channel_pgm_en15
=
channel_pgm_en
[
15
]
;
a
lways
@
(
posedge
mclk
)
channel_pgm_en15
<=
grant
&&
(
grant_chn
==
15
)
;
`endif
endmodule
...
...
memctrl/scheduler16.v
View file @
f948ab8f
...
...
@@ -27,10 +27,10 @@ module scheduler16 #(
input
clk
,
input
[
15
:
0
]
want_rq
,
// both want_rq and need_rq should go inactive after being granted
input
[
15
:
0
]
need_rq
,
input
en_sch
,
// needs to be disabled before next access can be scheduled
input
en_sch
edul
,
// needs to be disabled before next access can be scheduled
output
need
,
// granted access is "needed" one, not just "wanted"
output
grant
,
// single-cycle granted channel access
output
[
3
:
0
]
grant_chn
,
// granted channel number, valid with grant, stays valid until en_sch is deasserted
output
[
3
:
0
]
grant_chn
,
// granted channel number, valid with grant, stays valid until en_sch
edul
is deasserted
// todo: add programming sequencer address for software sequencer program? Or should it come from the channel?
input
[
3
:
0
]
pgm_addr
,
// channel address to program priority
input
[
width
-
1
:
0
]
pgm_data
,
// priority data for the channel
...
...
@@ -52,7 +52,7 @@ module scheduler16 #(
wire
[
3
:
0
]
index
;
// channel index to select
wire
index_valid
;
// selected index valid ("needed" or "wanted")
reg
grant_r
;
// 1 cycle long
reg
grant_sent
;
// turns on after grant, until en_sch is de-asserted
reg
grant_sent
;
// turns on after grant, until en_sch
edul
is de-asserted
reg
[
3
:
0
]
grant_chn_r
;
wire
grant_w
;
// assign event_w=new_want | new_need;
...
...
@@ -60,7 +60,7 @@ module scheduler16 #(
assign
next_need_conf
=
(
need_conf
&
need_rq
)
|
need_set
;
assign
grant
=
grant_r
;
assign
grant_chn
=
grant_chn_r
;
assign
grant_w
=
en_sch
&&
index_valid
&&
!
grant_sent
;
assign
grant_w
=
en_sch
edul
&&
index_valid
&&
!
grant_sent
;
generate
genvar
i
;
for
(
i
=
0
;
i
<
16
;
i
=
i
+
1
)
begin
:
pri_reg_block
...
...
@@ -129,8 +129,8 @@ module scheduler16 #(
grant_sent
<=
0
;
grant_chn_r
<=
0
;
end
else
begin
grant_r
<=
grant_w
;
// en_sch && index_valid && !grant_sent;
grant_sent
<=
(
grant_sent
&&
en_sch
)
||
grant_r
;
grant_r
<=
grant_w
;
// en_sch
edul
&& index_valid && !grant_sent;
grant_sent
<=
(
grant_sent
&&
en_sch
edul
)
||
grant_r
;
if
(
grant_w
)
grant_chn_r
<=
index
[
3
:
0
]
;
end
end
...
...
phy/mcontr_sequencer.v
View file @
f948ab8f
...
...
@@ -324,7 +324,7 @@ module mcontr_sequencer #(
.
NUM_CYCLES
(
4
)
,
.
ADDR_WIDTH
(
3
)
,
.
DATA_WIDTH
(
16
)
)
cmd_deser_
0
bit_i
(
)
cmd_deser_
16
bit_i
(
.
rst
(
rst
)
,
// input
.
clk
(
mclk
)
,
// input
.
ad
(
cmd_ad
)
,
// input[7:0]
...
...
x393.v
View file @
f948ab8f
...
...
@@ -316,6 +316,26 @@ module x393 #(
wire
refresh_en
;
wire
refresh_set
;
reg
[
AXI_WR_ADDR_BITS
-
1
:
0
]
axiwr_bram_waddr_d
;
reg
[
31
:
0
]
axiwr_bram_wdata_d
;
reg
mcontr_cmdseq_we
;
// .cmd0_clk (axi_aclk), // input
// .cmd0_we (en_cmd0_wr), // input
// .cmd0_addr (axiwr_bram_waddr[9:0]), // input[9:0]
// .cmd0_data (axiwr_bram_wdata[31:0]), // input[31:0]
// register address/data to write copmmand sequencer port 0 (PS)
always
@
(
posedge
axi_rst
or
posedge
axi_aclk
)
begin
if
(
axi_rst
)
mcontr_cmdseq_we
<=
1'b0
;
else
mcontr_cmdseq_we
<=
axiwr_bram_wen
&&
(((
axiwr_bram_waddr
^
CMD0_ADDR
)
&
CMD0_ADDR_MASK
)
==
0
)
;
end
always
@
(
posedge
axi_aclk
)
if
(
axiwr_bram_wen
)
begin
axiwr_bram_waddr_d
<=
axiwr_bram_waddr
;
axiwr_bram_wdata_d
<=
axiwr_bram_wdata
;
end
assign
port0_rd_match
=
(((
axird_bram_raddr
^
PORT0_RD_ADDR
)
&
PORT0_RD_ADDR_MASK
)
==
0
)
;
assign
en_cmd0_wr
=
axiwr_bram_wen
&&
(((
axiwr_bram_waddr
^
CMD0_ADDR
)
&
CMD0_ADDR_MASK
)
==
0
)
;
assign
en_port0_rd
=
axird_bram_ren
&&
port0_rd_match
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment