aboutsummaryrefslogtreecommitdiff
path: root/lab7bonus_top.sv
blob: d76cf7caf67b93b45a825ae66dbf54d2cadbc86a (plain) (blame)
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