Skip to content

Commit

Permalink
switched from subtract with borrow to subtract with carry. fixed bug …
Browse files Browse the repository at this point in the history
…in control for pus and pos.
  • Loading branch information
ept221 committed Apr 24, 2021
1 parent 23a5af3 commit e2af85d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 30 deletions.
56 changes: 47 additions & 9 deletions programs/divide.asm
Original file line number Diff line number Diff line change
@@ -1,25 +1,63 @@
;******************************************************************************
.define uart_baud, 0x0A
.define uart_ctrl, 0x0B
.define uart_buffer, 0x0C
;******************************************************************************

.code

ldi r14, 0xff ; setup the stack pointer
ldi r15, 0x00

ldi r0, 103 ; set the baud-rate to 9600
out r0, uart_baud

ldi r0, 253 ; dividend
ldi r1, 7 ; divisor
call divmod

loop: in r5, uart_ctrl
ani r5, 2
bz loop ; poll for empty buffer

out r2, uart_buffer ; print the quotient

hlt
;******************************************************************************
; r0 holds the dividend
; r1 holds the divisor
; r2 holds the quotient
; r3 holds the remainder

divide: push r0
divmod: push r0
push r4

csr 0b1110 ; clear the carry

ldi r3, 0 ; initilize the remander to zero
ldi r4, 8 ; initilize the counter
csr 0

divmod_loop: pus
cpi r4, 0 ; check the counter
bz divide_end ; branch if we've shifted all 8 times
adi r4, -1
pos
rlc r0 ; shift the dividend left and bring in the next bit of the quotient
rlc r3 ; shift the remainder left and bring in the next bit of the remainder

sub r3, r1 ; subtract the divisor from the remainder
bc divide_loop ; don't restore if the result was positive
add r3, r1 ; else restore
csr 0
br divide_loop

cpi r4, 0
bz divide_end ; finish if we've shifted all 8 times
divmod_end: pos

rlc r0 ; shift the dividend left and bring in the msb of the remainder
rlc r3 ; shift the remainder left and bring in the msb of the dividend
rlc r0 ; get the last bit of the quotient
mov r2, r0 ; copy the quotient into r2

divide_end: pop r4
pop r0
pop r0 ; restore the counter reg
pop r4 ; restore the dividend
ret
;******************************************************************************
32 changes: 16 additions & 16 deletions soc/src/cpu/alu.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ module alu(input wire [7:0] dataA,

always @(*) begin
case(mode)
4'b0000: {cout, out} = {cin,dataA}; // Pass A
4'b0001: {cout, out} = {cin,dataB}; // Pass B // Used by LDI and MOV
4'b0010: {cout, out} = {cin,dataA & dataB}; // AND
4'b0011: {cout, out} = {cin,dataA | dataB}; // OR
4'b0100: {cout, out} = {cin,dataA ^ dataB}; // XOR
4'b0101: {cout, out} = dataA + dataB; // ADD
4'b0110: {cout, out} = dataA + dataB + {7'b0,cin}; // ADC
4'b0111: {cout, out} = {(dataA > dataB),dataA}; // CMP // Sets carry on greater, passes dataA
4'b1000: {cout, out} = dataA - dataB; // SUB
4'b1001: {cout, out} = dataA - dataB - {7'b0,cin}; // SBB
4'b1010: {cout, out} = (dataA << 1); // SLL
4'b1011: {cout, out} = {dataA[0],(dataA >> 1)}; // SRL
4'b1100: {cout, out} = {dataA[0],(dataA >>> 1)}; // SRA
4'b1101: {cout, out} = {dataA,cin}; // RLC
4'b1110: {out, cout} = {cin,dataA}; // RRC
4'b1111: {cout, out} = {cin,~dataA}; // NOT
4'b0000: {cout, out} = {cin,dataA}; // Pass A
4'b0001: {cout, out} = {cin,dataB}; // Pass B // Used by LDI and MOV
4'b0010: {cout, out} = {cin,dataA & dataB}; // AND
4'b0011: {cout, out} = {cin,dataA | dataB}; // OR
4'b0100: {cout, out} = {cin,dataA ^ dataB}; // XOR
4'b0101: {cout, out} = dataA + dataB; // ADD
4'b0110: {cout, out} = dataA + dataB + {7'b0,cin}; // ADC
4'b0111: {cout, out} = {(dataA > dataB),dataA}; // CMP // Sets carry on greater, passes dataA
4'b1000: {cout, out} = {1'b0,dataA} + {1'b0,~dataB} + 8'b1; // SUB
4'b1001: {cout, out} = {1'b0,dataA} + {1'b0,~dataB} + {7'b0,cin}; // SBB
4'b1010: {cout, out} = (dataA << 1); // SLL
4'b1011: {cout, out} = {dataA[0],(dataA >> 1)}; // SRL
4'b1100: {cout, out} = {dataA[0],(dataA >>> 1)}; // SRA
4'b1101: {cout, out} = {dataA,cin}; // RLC
4'b1110: {out, cout} = {cin,dataA}; // RRC
4'b1111: {cout, out} = {cin,~dataA}; // NOT
endcase
end

Expand Down
10 changes: 5 additions & 5 deletions soc/src/cpu/control.v
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,10 @@ module control(input wire clk,
end
else if(PUS_TYPE) begin
regFileSrc = 1'b0; // aluOut, doesn't really matter
regFileOutBSelect = {iMemOut[11:9],1'b0}; // lower SP reg
regFileOutBSelect = {iMemOut[11:9],1'b0}; // lower SP reg so outputs SP for BC
regFileWriteEnable = 1'b0;
regFileAdd = 1'b1;
regFileConstSrc = 2'b00;
regFileConstSrc = 2'b01;
aluSrcASelect = 1'b1; // From zero-extended status register
aluSrcBSelect = 2'b00; // regFileOutB, doesn't really matter
aluMode = 4'b0000; // pass A
Expand All @@ -434,19 +434,19 @@ module control(input wire clk,
end
else if(POS_TYPE) begin
regFileSrc = 1'b0; // aluOut, doesn't really matter
regFileOutBSelect = {iMemOut[11:9],1'b0}; // lower SP reg
regFileOutBSelect = {iMemOut[11:9],1'b0}; // lower SP reg so outputs SP for BC
regFileWriteEnable = 1'b0;
regFileAdd = (state == PART1);
regFileConstSrc = 2'b00;
aluSrcASelect = 1'b0; // From register file, doesn't really matter
aluSrcBSelect = 2'b00; // regFileOutB, doesn't really matter
aluMode = 4'b0000; // Pass A, doesn't really matter
dMemDataSelect = 3'b000; // aluOut, doesn't really matter
dMemIOAddressSelect = 2'b00; // {regFileOutC,regFileOutB}
dMemIOAddressSelect = 2'b10; // {regFileOutC,regFileOutB} + 1
dMemIOWriteEn = 1'b0;
dMemIOReadEn = (state == PART1);
statusRegSrcSelect = 2'b10; // dMemIOOut[3:0]
flagEnable = 1'b1;
flagEnable = (state == PART2);
iMemAddrSelect = 3'b000; // pcOut
iMemReadEnable = (state == PART2);
pcWriteEn = (state == PART2);
Expand Down

0 comments on commit e2af85d

Please sign in to comment.