Hello,
I am trying to implement a burst transcation with SDRAM using Avalon MM
Interface.
The following Verilog code works fine for burstcount = 2:
1 | module hw_det_3by3(
|
2 | clk,
|
3 | reset,
|
4 | avs_csr_addr,
|
5 | avs_csr_write,
|
6 | avs_csr_writedata,
|
7 | avs_csr_read,
|
8 | avs_csr_readdata,
|
9 | avm_sdram_addr,
|
10 | avm_sdram_burstcount,
|
11 | avm_sdram_read,
|
12 | avm_sdram_waitrequest,
|
13 | avm_sdram_readdatavalid,
|
14 | avm_sdram_readdata
|
15 |
|
16 | );
|
17 |
|
18 | input wire clk;
|
19 | input wire reset;
|
20 |
|
21 | input wire [2:0] avs_csr_addr;
|
22 | input wire avs_csr_write;
|
23 | input wire [31:0] avs_csr_writedata;
|
24 | input wire avs_csr_read;
|
25 | output wire [31:0] avs_csr_readdata;
|
26 |
|
27 | output wire [31:0] avm_sdram_addr;
|
28 | output wire [2:0] avm_sdram_burstcount;
|
29 | output wire avm_sdram_read;
|
30 | input wire avm_sdram_waitrequest;
|
31 | input wire avm_sdram_readdatavalid;
|
32 | input wire [31:0] avm_sdram_readdata;
|
33 |
|
34 | reg [31:0] read_addr;
|
35 | reg load_minors = 0;
|
36 | reg count = 0;
|
37 | reg status = 0;
|
38 |
|
39 | reg [31:0] minor10;
|
40 | reg [31:0] minor11;
|
41 | reg [31:0] minor12;
|
42 | reg [31:0] minor20;
|
43 | reg [31:0] minor21;
|
44 | reg [31:0] minor22;
|
45 |
|
46 | reg sdram_read;
|
47 |
|
48 | reg [31:0] csr_readdata;
|
49 |
|
50 | assign avm_sdram_addr = read_addr;
|
51 | assign avm_sdram_burstcount = 2;
|
52 | assign avm_sdram_read = sdram_read;
|
53 |
|
54 | assign avs_csr_readdata = csr_readdata;
|
55 |
|
56 | always @ (posedge clk)
|
57 | begin
|
58 | if (avs_csr_write == 1)
|
59 | begin
|
60 | if (avs_csr_addr == 1)
|
61 | begin
|
62 | load_minors <= 1;
|
63 | read_addr <= avs_csr_writedata;
|
64 | end
|
65 | end
|
66 | if (load_minors == 1)
|
67 | begin
|
68 | load_minors <= 0;
|
69 | end
|
70 | end
|
71 |
|
72 | always @ (posedge clk)
|
73 | begin
|
74 | if (load_minors == 1)
|
75 | begin
|
76 | sdram_read <= 1;
|
77 | end
|
78 | else
|
79 | begin
|
80 | if (avm_sdram_waitrequest == 0)
|
81 | begin
|
82 | sdram_read <= 0;
|
83 | end
|
84 | end
|
85 | end
|
86 |
|
87 | always @ (posedge clk or posedge reset)
|
88 | begin
|
89 | if (reset == 1)
|
90 | begin
|
91 | count <= 0;
|
92 | status <= 0;
|
93 | end
|
94 | else if(avm_sdram_readdatavalid)
|
95 | begin
|
96 | case (count)
|
97 | 0: begin
|
98 | minor10 <= avm_sdram_readdata;
|
99 | end
|
100 | 1: begin
|
101 | minor11 <= avm_sdram_readdata;
|
102 | status <= 1;
|
103 | end
|
104 | endcase
|
105 | count <= count + 1;
|
106 | end
|
107 | end
|
108 |
|
109 | always @ (posedge clk)
|
110 | begin
|
111 | if(avs_csr_read == 1)
|
112 | begin
|
113 | case (avs_csr_addr)
|
114 | 0: csr_readdata <= status;
|
115 | 1: csr_readdata <= read_addr;
|
116 | 2: csr_readdata <= minor10;
|
117 | 3: csr_readdata <= minor11;
|
118 | endcase
|
119 | end
|
120 | end
|
121 |
|
122 | endmodule
|
Software Interface in NIOS:
1 | #include <stdio.h>
|
2 | #include "system.h"
|
3 | #include <io.h>
|
4 | #include <stdlib.h> /* rand(), RAND_MAX */
|
5 |
|
6 | int main()
|
7 | {
|
8 |
|
9 | float n = 1.25;
|
10 | float m = 2.5;
|
11 |
|
12 | printf("%x, %x\n", &n, &m);
|
13 |
|
14 | IOWR(HW_DET_3BY3_0_BASE, 1, &n);
|
15 |
|
16 | while (IORD(HW_DET_3BY3_0_BASE, 0) == 0){
|
17 | printf("%x\n", IORD(HW_DET_3BY3_0_BASE, 0));
|
18 | }
|
19 | printf("%x\n", IORD(HW_DET_3BY3_0_BASE, 1));
|
20 | printf("%x\n", IORD(HW_DET_3BY3_0_BASE, 2));
|
21 | printf("%x\n", IORD(HW_DET_3BY3_0_BASE, 3));
|
22 |
|
23 | return 0;
|
24 | }
|
However, when I make slight variations to implement the same
functionality for a burst of 3 words, then I get problems - 'status'
never changes to 1.
Does anyone have an idea why that is? I have been trying to solve this
for the past few hours now...
Also, is there are a possibility I can monitor my signals
(avm_sdram_writerequest, avm_sdram_readdatavalid etc.) during runtime?
Many thanks in advance.
Jimmy