aboutsummaryrefslogtreecommitdiff
path: root/hdl/hazard_unit.v
blob: 83531e7fc925f27dd171f2313f24f6d4b141f3f0 (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
67
68
69
70
71
72
73
74
75
76
77
`timescale 1ns / 1ps

module hazard_unit( input       clk,       //     isn't needed for now
                    input       rst,       //     isn't needed for now
                    input [4:0] ex_dst_reg,
                    input [4:0] mem_dst_reg,
                    input [4:0] id_rs,
                    input [4:0] id_rt,	

                    input wb_done_i,
                    
                    output pstop_o,

                    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      hazard_detected_o );

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

     assign pc_write       = ~hazard_detected_o;
     assign if_id_write_en = ~hazard_detected_o;
     
     reg mem_wait_r;
     reg hazard_detected;
     
     assign hazard_detected_o = hazard_detected;
     
     assign pstop_o = mem_wait_r;
     
     always@(posedge clk, posedge rst) begin
        if(rst)  
            mem_wait_r = 0;
        else if (wb_done_i)
            mem_wait_r = 0;
        else if (id_opcode == LW || id_opcode == SW)
            mem_wait_r = (id_opcode == LW || id_opcode == SW);
     end
     
     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