Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * Memory Harness with Wishbone Slave interface | |
3 | * | |
4 | * (C) Copyleft 2007 Simply RISC LLP | |
5 | * AUTHOR: Fabrizio Fazzino <fabrizio.fazzino@srisc.com> | |
6 | * | |
7 | * LICENSE: | |
8 | * This is a Free Hardware Design; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License | |
10 | * version 2 as published by the Free Software Foundation. | |
11 | * The above named program is distributed in the hope that it will | |
12 | * be useful, but WITHOUT ANY WARRANTY; without even the implied | |
13 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
14 | * See the GNU General Public License for more details. | |
15 | * | |
16 | * DESCRIPTION: | |
17 | * Filename is a parameter, and the corresponding file content | |
18 | * must follow the rules stated in Verilog standard for the | |
19 | * $readmemh() system task. | |
20 | * For instance if you don't change the default name you just | |
21 | * have to put a text file named "memory.hex" in your simulation | |
22 | * directory with the following content inside: | |
23 | * | |
24 | * // We start from address zero by default: | |
25 | * 1234567812345678 | |
26 | * FEDCBA9876543210 | |
27 | * // Now we jump to doubleword number 10 (i.e. address 80): | |
28 | * @ 10 | |
29 | * 02468ACE13579BDF | |
30 | * | |
31 | * This memory harness was originally based upon a Wishbone Slave | |
32 | * model written by Rudolf Usselmann <rudi@asics.ws> but now I've | |
33 | * written it again entirely from scratch. | |
34 | */ | |
35 | ||
36 | ||
37 | module mem_harness(sys_clock_i, sys_reset_i, wbs_addr_i, wbs_data_i, wbs_data_o, | |
38 | wbs_cycle_i, wbs_strobe_i, wbs_sel_i, wbs_we_i, wbs_ack_o); | |
39 | // syn black_box | |
40 | parameter addr_bits = 24; | |
41 | parameter addr_max = ((1 << addr_bits) - 1); | |
42 | parameter memfilename = "memory.hex"; | |
43 | parameter initmem = 0; | |
44 | parameter loadmem = 1; | |
45 | parameter memdefaultcontent = 64'b0; | |
46 | input sys_clock_i; | |
47 | input sys_reset_i; | |
48 | input wbs_cycle_i; | |
49 | input wbs_strobe_i; | |
50 | input [63:0] wbs_addr_i; | |
51 | input [63:0] wbs_data_i; | |
52 | input wbs_we_i; | |
53 | input [7:0] wbs_sel_i; | |
54 | output wbs_ack_o; | |
55 | output [63:0] wbs_data_o; | |
56 | ||
57 | reg wbs_ack_o; | |
58 | reg [63:0] wbs_data_o; | |
59 | reg /*sparse*/ | |
60 | [63:0] mem[addr_max:0]; | |
61 | wire [63:0] tmp_rd; | |
62 | wire [63:0] tmp_wd; | |
63 | integer i; | |
64 | ||
65 | ||
66 | /* synthesis translate_off */ | |
67 | initial begin | |
68 | $display("INFO: MEMH %m: Memory Harness with Wishbone Slave interface starting..."); | |
69 | $display("INFO: MEMH %m: %0d Address Bits / %0d Doublewords / %0d Bytes Total Memory", addr_bits, addr_max+1, (addr_max+1)*8); | |
70 | $readmemh(memfilename, mem); | |
71 | $display("INFO: MEMH %m: Memory initialization completed"); | |
72 | end | |
73 | ||
74 | /* synthesis translate_on */ | |
75 | ||
76 | assign tmp_rd = mem[wbs_addr_i[(addr_bits + 2):3]]; | |
77 | assign tmp_wd[63:56] = ((!wbs_sel_i[7]) ? tmp_rd[63:56] : | |
78 | wbs_data_i[63:56]); | |
79 | assign tmp_wd[55:48] = ((!wbs_sel_i[6]) ? tmp_rd[55:48] : | |
80 | wbs_data_i[55:48]); | |
81 | assign tmp_wd[47:40] = ((!wbs_sel_i[5]) ? tmp_rd[47:40] : | |
82 | wbs_data_i[47:40]); | |
83 | assign tmp_wd[39:32] = ((!wbs_sel_i[4]) ? tmp_rd[39:32] : | |
84 | wbs_data_i[39:32]); | |
85 | assign tmp_wd[31:24] = ((!wbs_sel_i[3]) ? tmp_rd[31:24] : | |
86 | wbs_data_i[31:24]); | |
87 | assign tmp_wd[23:16] = ((!wbs_sel_i[2]) ? tmp_rd[23:16] : | |
88 | wbs_data_i[23:16]); | |
89 | assign tmp_wd[15:8] = ((!wbs_sel_i[1]) ? tmp_rd[15:8] : wbs_data_i[15:8] | |
90 | ); | |
91 | assign tmp_wd[7:0] = ((!wbs_sel_i[0]) ? tmp_rd[7:0] : wbs_data_i[7:0]); | |
92 | ||
93 | always @(posedge sys_clock_i) begin | |
94 | if ((wbs_cycle_i & wbs_strobe_i) & (!wbs_we_i)) begin | |
95 | wbs_ack_o = 1; | |
96 | wbs_data_o = tmp_rd; | |
97 | end | |
98 | else if ((wbs_cycle_i & wbs_strobe_i) & wbs_we_i) begin | |
99 | wbs_ack_o = 1; | |
100 | wbs_data_o = 64'hzzzzzzzzzzzzzzzz; | |
101 | mem[wbs_addr_i[(addr_bits + 2):3]] = tmp_wd; | |
102 | end | |
103 | else | |
104 | begin | |
105 | wbs_ack_o = 0; | |
106 | wbs_data_o = 64'hzzzzzzzzzzzzzzzz; | |
107 | end | |
108 | end | |
109 | endmodule |