@@ -57,6 +57,25 @@ architecture neorv32_dma_rtl of neorv32_dma is
57
57
constant ctrl_done_c : natural := 30 ; -- r/-: transfer has completed
58
58
constant ctrl_busy_c : natural := 31 ; -- r/-: DMA transfer in progress
59
59
60
+ -- replicate byte 4 times --
61
+ function rep4_f (b : std_ulogic_vector (7 downto 0 )) return std_ulogic_vector is
62
+ begin
63
+ return b & b & b & b;
64
+ end function rep4_f ;
65
+
66
+ -- one-hot encoding --
67
+ function onehot_f (sel : std_ulogic_vector (1 downto 0 )) return std_ulogic_vector is
68
+ variable res_v : std_ulogic_vector (3 downto 0 );
69
+ begin
70
+ case sel is
71
+ when "00" => res_v := "0001" ;
72
+ when "01" => res_v := "0010" ;
73
+ when "10" => res_v := "0100" ;
74
+ when others => res_v := "1000" ;
75
+ end case ;
76
+ return res_v;
77
+ end function onehot_f ;
78
+
60
79
-- control and status register --
61
80
type ctrl_t is record
62
81
enable, start, err, done : std_ulogic ;
@@ -92,10 +111,10 @@ architecture neorv32_dma_rtl of neorv32_dma is
92
111
signal engine : engine_t;
93
112
94
113
-- address increment --
95
- signal src_add, dst_add : unsigned (31 downto 0 );
114
+ signal src_add, dst_add : unsigned (31 downto 0 );
96
115
97
116
-- data buffer --
98
- signal rdata, data_buf : std_ulogic_vector (31 downto 0 );
117
+ signal data_buf : std_ulogic_vector (31 downto 0 );
99
118
100
119
begin
101
120
@@ -304,6 +323,29 @@ begin
304
323
end process address_inc ;
305
324
306
325
326
+ -- Input Data Alignment -------------------------------------------------------------------
327
+ -- -------------------------------------------------------------------------------------------
328
+ src_align : process (rstn_i, clk_i)
329
+ begin
330
+ if (rstn_i = '0' ) then
331
+ data_buf <= (others => '0' );
332
+ elsif rising_edge (clk_i) then
333
+ if (engine.state = S_READ_RSP) then
334
+ if (engine.src_type(0 ) = '0' ) then -- byte
335
+ case engine.src_addr(1 downto 0 ) is
336
+ when "00" => data_buf <= rep4_f(dma_rsp_i.data( 7 downto 0 ));
337
+ when "01" => data_buf <= rep4_f(dma_rsp_i.data(15 downto 8 ));
338
+ when "10" => data_buf <= rep4_f(dma_rsp_i.data(23 downto 16 ));
339
+ when others => data_buf <= rep4_f(dma_rsp_i.data(31 downto 24 ));
340
+ end case ;
341
+ else -- word
342
+ data_buf <= dma_rsp_i.data;
343
+ end if ;
344
+ end if ;
345
+ end if ;
346
+ end process src_align ;
347
+
348
+
307
349
-- Bus Output Control ---------------------------------------------------------------------
308
350
-- -------------------------------------------------------------------------------------------
309
351
bus_control : process (engine, data_buf)
@@ -320,24 +362,31 @@ begin
320
362
dma_req_o.addr <= engine.src_addr(31 downto 2 ) & "00" ;
321
363
dma_req_o.rw <= '0' ;
322
364
if (engine.src_type(0 ) = '0' ) then -- byte
323
- dma_req_o.ben( to_integer ( unsigned ( engine.src_addr(1 downto 0 )))) <= '1' ;
365
+ dma_req_o.ben <= onehot_f( engine.src_addr(1 downto 0 ));
324
366
else -- word
325
367
dma_req_o.ben <= (others => '1' );
326
368
end if ;
327
369
else -- write access
328
370
dma_req_o.addr <= engine.dst_addr(31 downto 2 ) & "00" ;
329
371
dma_req_o.rw <= '1' ;
330
372
if (engine.dst_type(0 ) = '0' ) then -- byte
331
- dma_req_o.ben(to_integer (unsigned (engine.dst_addr(1 downto 0 )))) <= '1' ;
373
+ if (engine.bswap = '0' ) then
374
+ dma_req_o.ben <= onehot_f(engine.dst_addr(1 downto 0 ));
375
+ else
376
+ dma_req_o.ben <= onehot_f(not engine.dst_addr(1 downto 0 ));
377
+ end if ;
332
378
else -- word
333
379
dma_req_o.ben <= (others => '1' );
334
380
end if ;
335
381
end if ;
336
382
-- output data alignment --
337
- if (engine.dst_type(0 ) = '0' ) then -- byte
338
- dma_req_o.data <= data_buf(7 downto 0 ) & data_buf(7 downto 0 ) & data_buf(7 downto 0 ) & data_buf(7 downto 0 );
339
- else -- word
383
+ if (engine.bswap = '0' ) then
340
384
dma_req_o.data <= data_buf;
385
+ else -- swap Endianness
386
+ dma_req_o.data( 7 downto 0 ) <= data_buf(31 downto 24 );
387
+ dma_req_o.data(15 downto 8 ) <= data_buf(23 downto 16 );
388
+ dma_req_o.data(23 downto 16 ) <= data_buf(15 downto 8 );
389
+ dma_req_o.data(31 downto 24 ) <= data_buf( 7 downto 0 );
341
390
end if ;
342
391
-- request strobe --
343
392
if (engine.state = S_READ_REQ) or (engine.state = S_WRITE_REQ) then
@@ -346,34 +395,4 @@ begin
346
395
end process bus_control ;
347
396
348
397
349
- -- Input Data Alignment -------------------------------------------------------------------
350
- -- -------------------------------------------------------------------------------------------
351
- src_align : process (rstn_i, clk_i)
352
- begin
353
- if (rstn_i = '0' ) then
354
- data_buf <= (others => '0' );
355
- elsif rising_edge (clk_i) then
356
- if (engine.state = S_READ_RSP) then
357
- if (engine.src_type(0 ) = '0' ) then -- byte
358
- case engine.src_addr(1 downto 0 ) is
359
- when "00" => data_buf <= x"000000" & rdata(7 downto 0 );
360
- when "01" => data_buf <= x"000000" & rdata(15 downto 8 );
361
- when "10" => data_buf <= x"000000" & rdata(23 downto 16 );
362
- when others => data_buf <= x"000000" & rdata(31 downto 24 );
363
- end case ;
364
- else -- word
365
- data_buf <= rdata;
366
- end if ;
367
- end if ;
368
- end if ;
369
- end process src_align ;
370
-
371
- -- swap byte order (Endianness conversion) --
372
- bswap_gen:
373
- for i in 0 to 3 generate
374
- rdata(i* 8 + 7 downto i* 8 ) <= dma_rsp_i.data(i* 8 + 7 downto i* 8 ) when (engine.bswap = '0' ) else
375
- dma_rsp_i.data((32 - i* 8 )- 1 downto 32 - (i+ 1 )* 8 );
376
- end generate ;
377
-
378
-
379
398
end neorv32_dma_rtl ;
0 commit comments