fpga-lab-2/HDL/dec.sv

133 lines
2.1 KiB
Systemverilog

module dec
#(m = 8)
(
//clock and reset
input logic clk, clrn,
//control slave
input logic ctl_wr, ctl_rd,
input logic ctl_addr,
input logic [31:0] ctl_wrdata,
output logic [31:0] ctl_rddata,
//memory slave
input logic ram_wr,
input logic [1:0] ram_addr,
input logic [31:0] ram_wrdata,
//external ports
input logic train,
output logic red, yellow, green
);
logic run;
logic [1:0] divider;
logic [m-1:0] divisor;
logic [1:0] contr;
logic [2:0] colors;
logic [m-1:0] cntdiv;
logic enacnt;
//control slave logic
always_ff @ (posedge clk or negedge clrn)
begin
if (!clrn)
begin
run <= 0;
divider <= 0;
end
else
begin
if (ctl_wr)
begin
case (ctl_addr)
1'b0: run <= ctl_wrdata[0];
1'b1: divider <= ctl_wrdata[1:0];
endcase
end
end
end
always_comb
begin
case (ctl_addr)
1'b0: ctl_rddata = {31'b0,run};
1'b1: ctl_rddata = {30'b0,divider};
default: ctl_rddata = 'bx;
endcase
end
//semaphore logic
always_ff @ (posedge clk or negedge clrn)
begin
if (!clrn) cntdiv<=0;
else
begin
if (train | ~run) cntdiv<=0;
else
begin
if (enacnt) cntdiv<=0;
else cntdiv<=cntdiv+1;
end
end
end
always_comb
begin
enacnt=(cntdiv==divisor);
end
always_ff @ (posedge clk or negedge clrn)
begin
if (!clrn)
begin
colors <= 3'b100;
end
else
begin
if (train | ~run)
begin
colors <= 3'b100;
end
else
begin
if (enacnt)
begin
case (colors)
3'b100: colors <= 3'b010;
3'b010: colors <= 3'b011;
3'b011: colors <= 3'b001;
3'b001: colors <= 3'b001;
default: colors <= 3'b100;
endcase
end
end
end
end
always_comb
begin
case (colors)
3'b100: contr = 2'b00;
3'b010: contr = 2'b01;
3'b011: contr = 2'b10;
3'b001: contr = 2'b11;
default : contr = 2'b00;
endcase
end
assign red = colors[2];
assign yellow = colors[1];
assign green = colors[0];
periodram b2v_inst3(
.clock(clk),
.data (ram_wrdata),
.wraddress (ram_addr),
.wren (ram_wr),
.rdaddress({divider,contr}),
.q(divisor)
);
endmodule