aboutsummaryrefslogtreecommitdiff
path: root/hdl/hazard_unit.v
blob: 627c1621563a79c43b7d49e136129bfacc652a61 (plain)
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
`timescale 1ns / 1ps

module hazard_unit(
	input       clk, 
  input       rst,
	input [4:0] ex_dst_reg,
	input [4:0] mem_dst_reg,
	input [4:0] id_rs,
	input [4:0] id_rt,
	      
	input [5:0] mem_opcode, 
	input [5:0] ex_opcode, 
	input [5:0] id_opcode,

  input       id_rt_is_source,
  input       ex_reg_write,
  input       mem_reg_write,

  output      pc_write,
  output      if_id_write_en,
  output reg  hazard_detected
);

   localparam 
     LW = 6'b100011, 
     BEQ=6'b000100;


   assign pc_write = ~hazard_detected;
   assign if_id_write_en = ~hazard_detected;

   reg [1:0]        coincidence;
   
   always @*
     begin
        coincidence = 0;

        if (ex_reg_write && ( (id_rs == ex_dst_reg) | ( (id_rt == ex_dst_reg) && id_rt_is_source)))
          coincidence[0] = 1'b1;
        else if (mem_reg_write && ( (id_rs == mem_dst_reg) | ( (id_rt == mem_dst_reg) && id_rt_is_source)))
          coincidence[1] = 1'b1;        
     end


   always @*
     begin
        hazard_detected = 0;
        
        if (coincidence [0])
          begin
             if ( id_opcode == BEQ && ex_opcode == LW )
               hazard_detected = 1;
             else if ( id_opcode == BEQ && ex_opcode != LW)
               hazard_detected = 1;
             else if ( id_opcode != BEQ && ex_opcode == LW)
               hazard_detected = 1;             
          end
        else if (coincidence [1])
          begin
             if (id_opcode == BEQ && mem_opcode == LW)
               hazard_detected = 1;             
          end
     end
     
   
endmodule