master.v 1.98 KB
Newer Older
1
/*
2
 * Milkymist SoC
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

module master #(
	parameter id = 0,
	parameter nreads = 128,
	parameter nwrites = 128,
	parameter p = 4
) (
	input sys_clk,
	input sys_rst,
	
	output reg [31:0] dat_w,
	input [31:0] dat_r,
	output reg [31:0] adr,
	output [2:0] cti,
	output reg we,
	output reg [3:0] sel,
	output cyc,
	output stb,
	input ack,
	
	output reg tend
);

integer rcounter;
integer wcounter;
reg active;

assign cyc = active;
assign stb = active;
assign cti = 0;

always @(posedge sys_clk) begin
	if(sys_rst) begin
		dat_w = 0;
		adr = 0;
		we = 0;
		sel = 0;
		active = 0;
		rcounter = 0;
		wcounter = 0;
		tend = 0;
	end else begin
		if(ack) begin
			if(~active)
				$display("[M%d] Spurious ack", id);
			else begin
				if(we)
					$display("[M%d] Ack W: %x:%x [%x]", id, adr, dat_w, sel);
				else
					$display("[M%d] Ack R: %x:%x [%x]", id, adr, dat_r, sel);
			end
			active = 1'b0;
		end else if(~active) begin
			if(($random % p) == 0) begin
				adr = $random;
				adr = adr % 5;
				adr = (adr << (32-3)) + id;
				sel = sel + 1;
				active = 1'b1;
				if(($random % 2) == 0) begin
					/* Read */
					we = 1'b0;
					rcounter = rcounter + 1;
				end else begin
					/* Write */
					we = 1'b1;
					dat_w = ($random << 16) + id;
					wcounter = wcounter + 1;
				end
			end
		end
		tend = (rcounter >= nreads) && (wcounter >= nwrites);
	end
end

endmodule