1
2
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
|
`define MNONE 2'b00
`define MREAD 2'b01
`define MWRITE 2'b10
module lab7bonus_top(KEY,SW,LEDR,HEX0,HEX1,HEX2,HEX3,HEX4,HEX5);
input [3:0] KEY;
input [9:0] SW;
output reg [9:0] LEDR;
output [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5;
reg [8:0] mem_addr;
reg [7:0] read_address, write_address, next_LEDR, onto_LEDR;
reg write, enable;
reg [15:0] dout, din, read_data, write_data, ir;
wire [1:0] mem_cmd;
reg msel;
wire N, V, Z;
RAM MEM(.clk (~KEY[0]),
.read_address (read_address),
.write_address (write_address),
.write (write),
.din (din),
.dout (dout)
);
cpu CPU(.clk (~KEY[0]),
.reset (~KEY[1]),
.read_data (read_data),
.write_data(write_data),
.mem_addr(mem_addr),
.mem_cmd(mem_cmd),
.N(N),
.V(V),
.Z(Z)
);
always_comb begin
msel = mem_addr[8]; //checks the last bit to check the indicated address. 0 would mean below 255 and 1 would mean abouve 256
write = ({mem_cmd, msel} == {`MWRITE, 1'b0}); //write choosing
enable = ({mem_cmd, msel} == {`MREAD, 1'b0}); //the and gates and stuff
write_address = mem_addr[7:0];
read_address = mem_addr[7:0];
din = write_data;
read_data = enable ? dout : {16{1'bz}}; //tri-state driver
if ({mem_addr, mem_cmd} == {9'h140, `MREAD}) read_data = {8'b0, SW[7:0]}; //desing own logic this reads the switches if mem_cmd and addr are according
else read_data = read_data;
if ({mem_addr, mem_cmd} == {9'h100, `MWRITE}) next_LEDR = write_data[7:0]; //design own logic this writes to the switches if mem_cmd and addr are according
else next_LEDR = 8'bx;;
end
always_ff @(posedge ~KEY[0]) begin
LEDR[7:0] = next_LEDR;
end
endmodule
// Ram block obtained form slide set 11
module RAM(clk,read_address,write_address,write,din,dout);
parameter data_width = 16;
parameter addr_width = 8;
parameter filename = "data.txt";
input clk;
input [addr_width-1:0] read_address, write_address;
input write;
input [data_width-1:0] din;
output [data_width-1:0] dout;
reg [data_width-1:0] dout;
reg [data_width-1:0] mem [2**addr_width-1:0];
initial $readmemb(filename, mem);
always @ (posedge clk) begin
if (write)
mem[write_address] <= din;
dout <= mem[read_address]; // dout doesn't get din in this clock cycle
// (this is due to Verilog non-blocking assignment "<=")
end
endmodule
|