1
0
mirror of https://github.com/olofk/serv.git synced 2026-02-27 08:49:04 +00:00

lh, lw, lbu, lhu, sb, sh, slti

This commit is contained in:
Olof Kindgren
2018-11-01 22:51:51 +01:00
parent c90920d9b2
commit 8409aa4c4b
4 changed files with 50 additions and 17 deletions

View File

@@ -76,11 +76,11 @@ module serv_top_tb;
if (d_ca_en & d_ca_cmd & (d_ca_adr == 32'h10000000))
catch_write <= 1'b1;
if (catch_write & d_dm_en & d_dm_msk[0]) begin
if (((d_ca_en & d_ca_cmd & (d_ca_adr == 32'h10000000)) |catch_write) & d_dm_en & d_dm_msk[0]) begin
dbg <= 1'b1;
$write("%c", d_dm_dat[7:0]);
$fflush();
catch_write = 1'b0;
catch_write <= 1'b0;
end
end
vlog_tb_utils vtu();

View File

@@ -27,6 +27,7 @@ module serv_alu
reg en_r;
wire v;
reg msb_lt = 1'b0;
reg init_r;
shift_reg #(.LEN (5)) shamt_reg
@@ -92,6 +93,7 @@ module serv_alu
assign o_rd = (i_rd_sel == ALU_RESULT_ADD) ? result_add :
(i_rd_sel == ALU_RESULT_SR) ? result_sh :
(i_rd_sel == ALU_RESULT_LT) ? (result_lt2 & init_r & ~i_init):
1'bx;
always @(posedge clk) begin
@@ -100,9 +102,9 @@ module serv_alu
msb_lt <= i_cmp_uns ? (~i_rs1 & i_op_b) : (i_rs1 & ~i_op_b);
end
// result_lt <= /*v^*/result_add;
en_r <= i_en;
init_r <= i_init;
end
endmodule

View File

@@ -25,7 +25,7 @@ module serv_decode
output o_mem_en,
output o_mem_cmd,
output o_mem_init,
output o_mem_dat_valid,
output reg o_mem_dat_valid,
input i_mem_busy,
output [2:0] o_funct3,
output reg o_imm,
@@ -116,9 +116,9 @@ module serv_decode
end
assign o_alu_shamt_en = (state == SH_INIT) & (cnt < 5);
assign o_alu_rd_sel = (o_funct3 == 3'b000) ? ALU_RESULT_ADD :
assign o_alu_rd_sel = (o_funct3 == 3'b000) ? ALU_RESULT_ADD :
(o_funct3[2:1] == 2'b01) ? ALU_RESULT_LT :
(o_funct3 == 3'b101) ? ALU_RESULT_SR :
(o_funct3 == 3'b101) ? ALU_RESULT_SR :
2'bxx;
assign o_mem_en = mem_op & cnt_en;
@@ -141,9 +141,17 @@ module serv_decode
(opcode == OP_OP) ? OP_B_SOURCE_RS2 :
1'bx;
assign o_mem_dat_valid = (o_funct3[1:0] == 2'b00) ? cnt < 8 :
(o_funct3[1:0] == 2'b01) ? cnt < 16 : 1'b1;
always @(o_funct3, cnt)
if (o_mem_init)
o_mem_dat_valid = 1'bx;
else
casez(o_funct3[1:0])
2'b00 : o_mem_dat_valid = (cnt < 8);
2'b01 : o_mem_dat_valid = (cnt < 16);
2'b10 : o_mem_dat_valid = 1'b1;
default: o_mem_dat_valid = 1'bx;
endcase
wire [4:0] opcode = i_i_rd_dat[6:2];
@@ -201,6 +209,7 @@ module serv_decode
IDLE : begin
if (go)
state <= (opcode == OP_BRANCH) ? COMPARE :
((opcode == OP_OPIMM) & (o_funct3[2:1] == 2'b01)) ? COMPARE :
mem_op ? MEM_INIT :
shift_op ? SH_INIT : RUN;
end

View File

@@ -31,6 +31,7 @@ module serv_mem_if
reg init_r;
reg en_r;
reg en_2r;
wire adr;
reg [31:0] dat = 32'd0;
reg signbit = 1'b0;
@@ -47,7 +48,7 @@ module serv_mem_if
shift_reg #(32) shift_reg_adr
(
.clk (i_clk),
.i_en (i_en),
.i_en (i_init),
.i_d (adr),
.o_q (o_d_ca_adr[0]),
.o_par (o_d_ca_adr[31:1])
@@ -55,24 +56,44 @@ module serv_mem_if
assign o_d_ca_cmd = i_cmd;
wire is_signed = i_funct3[2];
assign o_rd = i_dat_valid ? dat[0] : is_signed & signbit;
wire is_signed = ~i_funct3[2];
assign o_rd = i_dat_valid ? dat[0] : signbit & is_signed;
assign o_d_rd_rdy = !i_en; //Likely bug, but probably doesn't matter
wire is_word = i_funct3[1];
wire is_half = i_funct3[0];
wire is_byte = !(|i_funct3[1:0]);
wire [1:0] bytepos = o_d_ca_adr[1:0];
wire upper_half = bytepos[1];
assign o_d_dm_dat = dat;
assign o_d_dm_msk = is_word ? 4'b1111 :
is_half ? {{2{upper_half}}, ~{2{upper_half}}} :
4'd1 << bytepos;
reg [1:0] bytepos;
reg [4:0] cnt = 5'd0;
reg dat_en;
always @(i_funct3, cnt, bytepos)
casez(i_funct3[1:0])
2'b1? : dat_en = 1'b1;
2'b?1 : dat_en = bytepos[1] ? (cnt<16) : 1'b1;
2'b00 : dat_en = (bytepos == 2'd3) ? (cnt <8) :
(bytepos == 2'd2) ? (cnt < 16) :
(bytepos == 2'd1) ? (cnt < 24) : 1'b1;
endcase
always @(posedge i_clk) begin
signbit <= dat[0];
cnt <= cnt + i_init;
if (i_en & !en_r)
bytepos[0] <= adr;
if (en_r & !en_2r)
bytepos[1] <= adr;
if (i_dat_valid)
signbit <= dat[0];
if (i_en & i_init)
o_busy <= 1'b1;
@@ -90,6 +111,7 @@ module serv_mem_if
end
en_r <= i_en;
en_2r <= en_r;
init_r <= i_init;
if (ca_en)
o_d_ca_vld <= 1'b0;
@@ -102,7 +124,7 @@ module serv_mem_if
else if (init_r & !i_init)
o_d_dm_vld <= i_cmd;
if (i_en)
if (i_en & dat_en)
dat <= {i_rs2,dat[31:1]};
end
endmodule